题目:
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 1:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
return [9, 8, 6, 5, 3]
Example 2:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
return [6, 7, 6, 0, 4]
Example 3:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
return [9, 8, 9]
分析:
1、结果的k位可以是从第一个数组取0位,从第二个数组取k位;或者从第一个数组取1位,从第二个数组取k-1位;依次类推。从第一个数组取i位最大数x,从第二个数组取(k-i)位最大数y,再把x和y合并起来。
2、从一个数组中保持原顺序地取出k个数,使得这k个数组成最大的数字的方法是:
记结果数组为result,原数组为nums。从左往右遍历nums,①如果result不满k个数,那么把nums的一个数放入result中。②否则要考虑是否替换掉result中原有的数。从后往前遍历result数组,比result中比nums[i]小的数字都是应该替换掉的,除非nums剩下的数字不能够填满result。
代码:
class Solution {
public:
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
int n=nums1.size(),m=nums2.size();
vector<int> res;
for(int i=0;i<=k;i++)
{
if(k-i>m) continue;
if(i>n) break;
vector<int> curNums1 = maxNumber(nums1,i);//从第一个数组中取i个
vector<int> curNums2 = maxNumber(nums2,k-i);//从第二个数组中取k-i个
vector<int> curNums = myMerge(curNums1,curNums2);//合并两个数组
if(greater(curNums,0,res,0)) res=curNums;//如果这样分的结果比原来的大,更新
}
return res;
}
vector<int> maxNumber(vector<int>& nums,int k)//求一个数组中能组成的k位最大数
{
vector<int> result(k,0);
int j=-1,n=nums.size();
for(int i=0;i<n;i++)
{
while( j>=0 && (n-i)>=(k-j) && nums[i]>result[j] ) j--;
if(j<k-1)
{
j++;
result[j] = nums[i];
}
}
return result;
}
vector<int> myMerge(vector<int>& nums1,vector<int>& nums2)//合并两个数组
{
int len1=nums1.size(),len2=nums2.size();
vector<int> result(len1+len2);
int i=0,j=0,k=0;
while(k<len1+len2)
{
if(i<len1&&greater(nums1,i,nums2,j)) result[k++] = nums1[i++];
else result[k++] = nums2[j++];
}
return result;
}
bool greater(vector<int>& nums1,int i,vector<int>& nums2,int j)//如果第一个数(从i往后)大于第二个数(从j往后),返回true
{
int len1=nums1.size(),len2=nums2.size();
while(i<len1 && j<len2 && nums1[i]==nums2[j]){i++;j++;}
if(i==len1) return false;
if(j==len2) return true;
return nums1[i]>nums2[j];
}
};
时间复杂度:O(n*m*k)