leetcode 321
问题 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.
Note: You should try to optimize your time and space complexity.
Example 1:
1 2 3 4 5 6 Input: nums1 = [3, 4, 6, 5] nums2 = [9, 1, 2, 5, 8, 3] k = 5 Output: [9, 8, 6, 5, 3]
Example 2:
1 2 3 4 5 6 Input: nums1 = [6, 7] nums2 = [6, 0, 4] k = 5 Output: [6, 7, 6, 0, 4]
Example 3:
1 2 3 4 5 6 Input: nums1 = [3, 9] nums2 = [8, 9] k = 3 Output: [9, 8, 9]
分析 求解这个问题首先要求解两个子问题。
给定一个数组 vector<int> nums
,从中求出一个长度为 x
的子序列,使其所代表的数字最大。
给定两个数组,将其按序分配合并,返回最大可能的数组,要保证元素在新数组中相对位置与原数组相同。
NOTE: 这两个子问题的求解都比较典型和重要。merge的时间复杂度是 $O((n+m)^2)$ ,整体的时间复杂度$O(k(n+m)^2)$
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 class Solution {public : vector <int > maxNumber(vector <int >& nums1, vector <int >& nums2, int k) { int n1 = nums1.size(); int n2 = nums2.size(); vector <int > ans = {}; for (int i = 0 ; i <= k; ++i) { if (i > n1 || k-i > n2) continue ; vector <int > candi = mergeArr(getArr(nums1, i), getArr(nums2, k-i)); if (candi.size() > ans.size() || (candi.size() == ans.size() && candi > ans)) ans = candi; } return ans; } vector <int > getArr(vector <int > &nums, int x) { if (x == 0 ) return {}; int to_pop = nums.size() - x; vector <int > ret; for (int a: nums) { while (ret.size() != 0 && ret.back() < a && to_pop > 0 ) { ret.pop_back(); to_pop--; } ret.push_back(a); } return vector <int >(ret.begin(), ret.begin()+x); } bool geater (vector <int > &a, int i, vector <int > &b, int j) { while (i < a.size() && j < b.size()) { if (a[i] > b[j]) return true ; if (a[i] < b[j]) return false ; i++; j++; } if (i == a.size()) return false ; return true ; } vector <int > mergeArr(vector <int > a, vector <int > b) { int n = a.size() + b.size(); vector <int > ret(n); for (int k = 0 , i = 0 , j = 0 ; k < n; ++k) { if (geater(a, i, b, j)) ret[k] = a[i++]; else ret[k] = b[j++]; } return ret; } };