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:
Input: nums1 =[3, 4, 6, 5]
nums2 =[9, 1, 2, 5, 8, 3]
k =5
Output:[9, 8, 6, 5, 3]
/* 保证相对顺序 从两个数组中取数 使得最后得到的结果最大
* 从第一个数组中跳出i个 第二个跳出j个最大的数 i+j=k 然后进行合并
* 然后从这些不同的组合中跳出一个最大的 vector 在stl中实现了比较方法(类似于按字典序)
*
* */
class Solution {
public:
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
vector<int> ret;
int len1=nums1.size(), len2=nums2.size();
for(int i=0;i<=len1;i++){
int j=k-i;
if(j>len2 || i>k) continue;
//cout<<i<<" "<<j<<endl;
// traver(maxComb(nums1, i));
// traver(maxComb(nums2, j));
// traver(realmerge(maxComb(nums1, i), maxComb(nums2, j)));
ret = max(ret, realmerge(maxComb(nums1, i), maxComb(nums2, j)));
}
return ret;
}
vector<int> maxComb(vector<int> &num, int k){// 从数组中取k位使结果最大
if(k==0) return {};
vector<int> monoret;
int cnt=num.size()-k;
for(int &n:num){
while(!monoret.empty() && cnt>0 && n>monoret.back()){
cnt--;
monoret.pop_back();
}
monoret.push_back(n);
// 对于76532 k=2 取76 就够了
}
monoret.resize(k);
return monoret;
}
// 按照合并有序链表的方式合并数组 错误的想法!!! [6(1), 7] [6(2), 0, 4] 按此合并结果为 6 6 7 0 4
// 其实真正的合并方法是: 如果当前数相同, 就按下一个数比较的结果来看 原因: 本次用了6(2) 下次不能用7 (所以要用字典序比较高的那位)
// 正确的做法: 两个数组按字典序比较 然后取当前最大数组的最高位
vector<int> merge(vector<int> nums1, vector<int> nums2){
int len1=nums1.size(), len2=nums2.size(),i=0,j=0;
vector<int> ret;
while(i!=len1 || j!=len2){
if(i==len1) ret.push_back(nums2[j++]);
else if(j==len2) ret.push_back(nums1[i++]);
else{
if(nums1[i]>nums2[j]) ret.push_back(nums1[i++]);
else ret.push_back(nums2[j++]);
}
}
return ret;
}
vector<int> realmerge(vector<int> nums1, vector<int> nums2){
vector<int> ret;
while(!nums1.empty() || !nums2.empty()){
vector<int> &tmp = nums1 > nums2 ? nums1 : nums2; // tmp指向字典序最大的那个数组
ret.push_back(tmp[0]);
tmp.erase(tmp.begin());
}
return ret;
}
void traver(vector<int> num){
for(int n:num) cout<<n<<" ";
cout<<endl;
}
};
在realmerge比较耗时。。之所以这么做,因为比较坑的是C++没有一个对vector索引的函数, 因此要自己写一个从指定位置开始比较的方法 。 当然也可以自己实现一下:
bool greater(vector<int>& nums1, int i, vector<int>& nums2, int j){
while (i < nums1.size() && j < nums2.size() && nums1[i] == nums2[j]){
i++;
j++;
}
return j == nums2.size() || (i<nums1.size() && nums1[i] > nums2[j]);
}