Notes:
This question is hard question, as labeled.
My first method is using memorization, memo[i][j][k] represents the largest new arr with size of k by using elements starting of i-th in arr1 and j-th in arr2. But it quickly receive TLE.
It turns out it can be solved greedily. After decomposing it into two simpler sub-problems, this question becomes not that hard.
1): find a largest subsequence with a size of k from a given array;
2): merge two given arrays to form the largest sequence (including all elements).
Both sub-questions above are not hard to implemented (maybe the second one need to deal with a specific case when the first elements are equal, but it is still not hard to deal with with a short comparison function, see below).
See the code below:
class Solution {
public:
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
int m = nums1.size(), n = nums2.size();
vector<int> res(k);
for(int i=max(0, k-n); i<=min(k, m); ++i) {
vector<int> v1 = find(nums1, i), v2 = find(nums2, k-i);
//find i from nums1, find (k-i) from nums2
vector<int> nt = merge(v1, v2);
if(larger(nt, 0, res, 0)) res = nt;
}
return res;
}
private:
vector<int> find(vector<int> &v, int k) {//find largest sequence with k elements;
vector<int> res(k);
int len = v.size();
for(int i=0, j=0; i<len; ++i) {
while(len-i+j>k && j>0 && res[j-1] < v[i]) --j;
if(j<k) res[j++] = v[i];
}
return res;
}
bool larger(vector<int> &v1, int i, vector<int> &v2, int j) {//very useful comp function
while(i<v1.size() && j<v2.size() && v1[i] == v2[j]) {
++i;
++j;
}
return j == v2.size() || (i < v1.size() && v1[i] > v2[j]);
}
vector<int> merge(vector<int> &v1, vector<int> &v2) {//merge two arrays into the largest one;
int m = v1.size(), n = v2.size();
vector<int> res(m+n);
for(int i=0, j=0, k = 0; i<v1.size() || j <v2.size(); ++k) {
res[k] = larger(v1, i, v2, j) ? v1[i++] : v2[j++];
}
return res;
}
};
There is another way to implement the find (vector<int>, int) function.
vector<int> find(vector<int> &v, int k) {//find k elements which gives the largest value;
vector<int> res(k);
int len = v.size();
if(!k && len < k) return res;
if(len == k) return v;
int left = 0, right = len - k, i = 0;
while(i < k) {
int idMax = left;//initialization
for(int i=left; i<=right; ++i) {
if(v[i] > v[idMax]) idMax = i;
}
res[i++] = v[idMax];
left = idMax + 1;//shift search range
++right;
}
return res;
}
Follow-up: all the questions can be converted into finding the largest string sequence with strings.
No comments:
Post a Comment