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]
解题思路
- 单调栈
- 贪心
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;
}
};