321. Create Maximum Number 找到兩個陣列中能合併的k個的最大數
Given two arrays of length m
and n
with
digits 0-9
representing two numbers. Create the maximum number of length k
<= m + n
from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k
digits.
You should try to optimize your time and space complexity.
Example 1:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
return [9, 8, 6, 5, 3]
Example 2:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
return [6, 7, 6, 0, 4]
Example 3:
nums1 = [3,
9]
nums2 = [8,
9]
k = 3
return [9, 8, 9]
解答:
題意:根據兩個陣列,從中找到部分陣列(原先位置序列不變),組合,得到新的陣列且最大值
思路:要找到組合的值最大,肯定也要找從一個數組中找的i個數最大,從另一個數組中找的k-i個數組成的數最大。那麼i從1~len遍歷就行
剩下的問題就是,對於一個數組,怎麼去除一個數使得剩下的數最大
1.用棧,遇到大的數就將棧中原來的數取出,再將大的數放入,遇到小的數放進去(對於一個數組取k個數)
2.就是把遞增到達後的數前面的數一個個刪除,得到每個長度時最大的數(用於對於兩個陣列進行合併的情況)
這裡就是用棧來解決得到最大數
In short we can first solve 2 simpler problem
Create the maximum number of one array
Create the maximum number of two array using all of their digits.
合併的時候注意:
不能用正常合併的思路,否則出現如下錯誤:
6 7
6 0 4
--> 6 6 7 0 4
正確:6 7 6 0 4
應該是,當遇到兩個數相同時,應該判斷這個數後面的兩個對應的數(7 0 )的大小
程式碼:
class Solution { public: //從陣列中找到k個最大的數,用棧的思想 vector<int> getmax(vector<int>& nums, int k){ vector<int>res(k,0); int i = 0, j = 0; //i代表nums的位置,j代表res的位置 int n = nums.size(); for(;i < nums.size(); i++){ while(n-i+j > k && j > 0 && res[j-1] < nums[i]) --j; //注意:這裡的n-i+j的作用是防止當遍歷到nums的最後k-j個位置的數時,不用再彈出了,直接賦值給res就行 if(j < k) res[j++] = nums[i]; } return res; } vector<int> merge(vector<int>res1, vector<int>res2){ int i = 0, j = 0, k = 0; vector<int>res(res1.size() + res2.size(), 0); while(i < res1.size() && j < res2.size()){ if(greaters(res1, i, res2, j)) res[k++] = res1[i++]; else res[k++] = res2[j++]; } while(i < res1.size()) res[k++] = res1[i++]; while(j < res2.size()) res[k++] = res2[j++]; return res; } bool greaters(vector<int>res, int i, vector<int>ans, int j){ while(i < res.size() && j < ans.size() && res[i] ==ans[j]){ ++i; ++j; } return (j == ans.size() || (i < res.size() && j < ans.size() && res[i] > ans[j])); } vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) { int len1 = nums1.size(); int len2 = nums2.size(); vector<int>ans(k, 0); for(int i = max(0, k - len2); i <= min(len1, k); i++){ //取的個數 vector<int> nums_max1 = getmax(nums1, i); vector<int> nums_max2 = getmax(nums2, k-i); vector<int>res = merge(nums_max1, nums_max2); if(greaters(res, 0, ans, 0)) ans = res; } return ans; } };