# 拼接最大数

给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。

求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。

说明: 请尽可能地优化你算法的时间和空间复杂度。

示例 1:

输入:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
输出:
[9, 8, 6, 5, 3]

示例 2:

输入:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
输出:
[6, 7, 6, 0, 4]

示例 3:

输入:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
输出:
[9, 8, 9]

以下错误的选项是?

## aop ### before ```cpp #include using namespace std; ``` ### after ```cpp int main() { Solution sol; vector nums1 = {3, 4, 6, 5}; vector nums2 = {9, 1, 2, 5, 8, 3}; int k = 5; vector res = sol.maxNumber(nums1, nums2, k); for (auto i : res) cout << i << " "; return 0; } ``` ## 答案 ```cpp class Solution { public: struct node { int val; int vec; int pos; }; static bool cmp(node a, node b) { return a.val > b.val; } vector maxNumber(vector &nums1, vector &nums2, int k) { int n = nums1.size(); int m = nums2.size(); struct node all[m + n]; vector ans; for (int i = 0; i < n; i++) { all[i].vec = 1; all[i].val = nums1[i]; all[i].pos = i; } for (int i = 0; i < m; i++) { all[i + n].vec = 2; all[i + n].val = nums2[i]; all[i + n].pos = i; } sort(all, all + m + n, cmp); int now1 = 0; int now2 = 0; int st = 0; while (st != n + 1) { for (int i = 0; i < n + m; i++) { if (all[i].pos >= now1 && n - all[i].pos + m - now2 >= k - st) { ans.push_back(all[i].val); now1 = all[i].pos + 1; st++; break; } } } return ans; } }; ``` ## 选项 ### A ```cpp class Solution { public: vector getNumsFromVector(vector &nums, int k) { int n = nums.size(); if (n == 0) return {}; vector stack; stack.push_back(nums[0]); for (int i = 1; i < n; ++i) { while (!stack.empty() && nums[i] > stack.back() && (n - i > k - (int)stack.size())) { stack.pop_back(); } stack.push_back(nums[i]); } if (stack.size() > k) { vector res(stack.begin(), stack.begin() + k); return res; } return stack; } int maxNumsVector(vector &nums1, int index1, vector &nums2, int index2) { int m = nums1.size(), n = nums2.size(); if (m == 0) return 2; if (n == 0) return 1; int p1 = index1, p2 = index2; for (; p1 < m && p2 < n; ++p1, ++p2) { if (nums1[p1] < nums2[p2]) { return 2; } if (nums1[p1] > nums2[p2]) { return 1; } } if (p1 < m) { return 1; } else { return 2; } } vector merge(vector &nums1, vector &nums2) { int m = nums1.size(), n = nums2.size(); if (m == 0) return nums2; if (n == 0) return nums1; vector res(m + n, 0); int p1 = 0, p2 = 0; int i = 0; while (p1 < m && p2 < n) { if (nums1[p1] < nums2[p2]) { res[i++] = nums2[p2++]; } else if (nums1[p1] == nums2[p2]) { if (maxNumsVector(nums1, p1, nums2, p2) == 1) { res[i++] = nums1[p1++]; } else { res[i++] = nums2[p2++]; } } else { res[i++] = nums1[p1++]; } } while (p1 < m) { res[i++] = nums1[p1++]; } while (p2 < n) { res[i++] = nums2[p2++]; } return res; } vector maxNumber(vector &nums1, vector &nums2, int k) { int m = nums1.size(); int n = nums2.size(); int begin = max(0, k - n), end = min(k, m); vector ansNums(k, 0); for (int i = begin; i <= end; ++i) { vector tempNums1 = getNumsFromVector(nums1, i); vector tempNums2 = getNumsFromVector(nums2, k - i); vector mergeRes = merge(tempNums1, tempNums2); if (maxNumsVector(ansNums, 0, mergeRes, 0) == 2) { ansNums = mergeRes; } } return ansNums; } }; ``` ### B ```cpp class Solution { public: vector find_kMax(vector &num, int k) { vector res; int i = 0; while (k > 0) { int idx = i; for (; i < num.size() - k + 1; ++i) { if (num[i] > num[idx]) idx = i; } res.push_back(num[idx]); i = idx + 1; --k; } return res; } vector merge(vector &nums1, vector &nums2) { vector res; for (auto iter1 = nums1.begin(), iter2 = nums2.begin(); iter1 != nums1.end() || iter2 != nums2.end();) { if (lexicographical_compare(iter1, nums1.end(), iter2, nums2.end())) res.push_back(*iter2++); else res.push_back(*iter1++); } return res; } vector maxNumber(vector &nums1, vector &nums2, int k) { vector res; for (int i = 0; i <= k; ++i) { int j = k - i; if (i > nums1.size() || j > nums2.size()) continue; auto tmp1 = find_kMax(nums1, i); auto tmp2 = find_kMax(nums2, j); res = max(res, merge(tmp1, tmp2)); } return res; } }; ``` ### C ```cpp class Solution { public: vector maxNumber(vector &nums1, vector &nums2, int k) { int m = nums1.size(), n = nums2.size(); vector 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 maxVector(vector nums, int k) { int drop = nums.size() - k; vector 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 mergeVector(vector nums1, vector nums2) { vector res; while (nums1.size() + nums2.size()) { vector &tmp = nums1 > nums2 ? nums1 : nums2; res.push_back(tmp[0]); tmp.erase(tmp.begin()); } return res; } }; ```