1. 程式人生 > >321. Create Maximum Number 找到兩個陣列中能合併的k個的最大數

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;
}
};