Create Maximum Number(Hard)


题目描述

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

Given nums1 = [3, 4, 6, 5], nums2 = [9, 1, 2, 5, 8, 3], k = 5 return [9, 8, 6, 5, 3]

Given nums1 = [6, 7], nums2 = [6, 0, 4], k = 5 return [6, 7, 6, 0, 4]

Given nums1 = [3, 9], nums2 = [8, 9], k = 3 return [9, 8, 9]

题目链接

解题思路

  1. 单调栈
  2. 贪心

time complexity:O(n^3)

space complexity: O(n)

参考代码

class Solution {
public:
    /**
     * @param nums1 an integer array of length m with digits 0-9
     * @param nums2 an integer array of length n with digits 0-9
     * @param k an integer and k <= m + n
     * @return an integer array
     */


    bool greater(const vector<int> &nums1, const vector<int> &nums2, int i, int j) {
        int n = nums1.size();
        int m = nums2.size();
        while (i < n && j < m) {
            if (nums1[i] == nums2[j]) {
                ++ i; ++ j;
            } else {
                return nums1[i] > nums2[j];
            }
        }
        if (i >= n) return false;
        return true;
    }

    vector<int> maxNumber(const vector<int> &nums, int k) {
        int n = nums.size();
        vector<int> ans;
        for (int i = 0; i < n; ++ i) {
            while (ans.size() && n - i - 1 + ans.size() >= k && ans.back() < nums[i]) {
                ans.pop_back();
            }
            if (ans.size() < k) ans.emplace_back(nums[i]);
        }
        return ans;
    }

    vector<int> merge(const vector<int> &nums1, const vector<int> &nums2) {
        int n = nums1.size();
        int m = nums2.size();
        vector<int> ans;
        for (int i = 0, j = 0; i < n || j < m; ) {
            if (greater(nums1, nums2, i, j)) {
                ans.emplace_back(nums1[i]);
                ++ i;
            } else {
                ans.emplace_back(nums2[j]);
                ++ j;
            }
        }
        return ans;
    }


    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
        // Write your code here
        int n = nums1.size();
        int m = nums2.size();
        if (n == 0) return maxNumber(nums2, k);
        else if (m == 0) return maxNumber(nums1, k);

        vector<int> ans(k);
        for (int i = 0; i < n && i < k; ++ i) {
            if (k - i - 1 > m) continue;
            vector<int> candidate = merge(maxNumber(nums1, i + 1), maxNumber(nums2, k - i - 1));
            if (greater(candidate, ans, 0, 0)) ans = candidate;
        }
        return ans;
    }

};

results matching ""

    No results matching ""