1. 程式人生 > >[LeetCode] Create Maximum Number 建立最大數

[LeetCode] Create Maximum Number 建立最大數

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]

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

這道題給了我們兩個陣列,裡面數字是無序的,又給我們一個k值為k <= m + n,然後我們從兩個陣列中共挑出k個數,數字之間的相對順序不變,求能組成的最大的數。這道題的難度是Hard,博主木有想出解法,參考網上大神們的解法來做的。由於k的大小不定,所以有三種可能,第一種是當k為0時,兩個陣列中都不取數;第二種是當k不大於其中一個數組的長度時,有可能只從一個數組中取數;第三種情況是k大於其中一個數組的長度,則需要從兩個陣列中分別取數,至於每個陣列中取幾個,每種情況都要考慮到,然後每次更結果即可。對於分別從兩個陣列中取數字的情況,我們需要將兩個取出的小陣列混合排序成一個數組,小陣列中各自的數字之間的相對順序不變。我們還需要一個函式來從陣列中取若干個數字的函式,而且取出的數要最大。比如當前陣列長度為n,需要取出k個數字,我們定義一個變數drop = n - k,表示需要丟棄的數字的個數,我們遍歷陣列中的數字,進行下列迴圈,如果此時drop為整數,且結果陣列長度不為0,結果陣列的尾元素小於當前遍歷的元素,則去掉結果陣列的尾元素,此時drop自減1,重複迴圈直至上述任意條件不滿足為止,然後把當前元素加入結果陣列中,最後我們返回結果陣列中的前k個元素。對於兩個陣列的混合,我們只要從兩個陣列開頭每次取兩個,把大的加入結果陣列,然後刪掉這個大的,然後繼續取一對比較,直到兩個陣列都為空停止。參見程式碼如下:

class Solution {
public:
    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
        int m = nums1.size(), n = nums2.size();
        vector<int> res;
        for (int i = max(0, k - n); i <= min(k, m); ++i) {
            res = max(res, mergeVector(maxVector(nums1, i), maxVector(nums2, k - i)));
        }
        return res;
    }
    vector<int> maxVector(vector<int> nums, int k) {
        int drop = nums.size() - k;
        vector<int> res;
        for (int num : nums) {
            while (drop && res.size() && res.back() < num) {
                res.pop_back();
                --drop;
            }
            res.push_back(num);
        }
        res.resize(k);
        return res;
    }
    vector<int> mergeVector(vector<int> nums1, vector<int> nums2) {
        vector<int> res;
        while (nums1.size() + nums2.size()) {
            vector<int> &tmp = nums1 > nums2 ? nums1 : nums2;
            res.push_back(tmp[0]);
            tmp.erase(tmp.begin());
        }
        return res;
    }
};

類似題目:

參考資料: