广州已经入秋了,天气慢慢变冷,虽然冷得不是那么明显,所以还是经常刷刷题暖暖身吧!!废话不说,直接上题:
题目:
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]
Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.
Subscribe to see which companies asked this question
源码:
class Solution {
public:
vector<vector<int>>get_max_number(vector<int>&nums){
int size = nums.size();
vector<vector<int>>n1(size + 1);
vector<int>::iterator j,k;
//获取nums1每位最大的数
bool flag = true;
for (int i = size; i >= 1; i--){
flag = true;
if (i == size)n1[i] = nums;
else{
n1[i] = n1[i + 1];
for (j = ++n1[i].begin(); j != n1[i].end(); j++){
if (*j > *(j - 1)){
j=n1[i].erase(j - 1);//清除前一位
flag = false;
break;
}
}
if (flag){
n1[i].pop_back();
}
}
}
return n1;
}
vector<int>merge(int n1, vector<int>&r1, int n2, vector<int>&r2){
vector<int>re;
int count1 = 0;
int count2 = 0;
while (count1 < n1&&count2 < n2){
if (r1[count1] < r2[count2])re.push_back(r2[count2++]);
else if (r1[count1] > r2[count2]) re.push_back(r1[count1++]);
else{//如果两个数相等
int s1 = count1, s2 = count2;
while (s1 < n1&&s2 < n2&&r1[s1] == r2[s2]){//开始比较
s1++;
s2++;
}
if (s1 == n1 || (s2<n2&&r2[s2]>r1[s1]))re.push_back(r2[count2++]);
else re.push_back(r1[count1++]);
}
}
if (count1 == n1){//r1先结束
for (int i = count2; i < n2; i++)re.push_back(r2[i]);
}
if (count2 == n2){//r1先结束
for (int i = count1; i < n1; i++)re.push_back(r1[i]);
}
return re;
}
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
int size1 = nums1.size();
int size2 = nums2.size();
vector<vector<int>>r1, r2;
r1 = get_max_number(nums1);
r2 = get_max_number(nums2);
vector<int>re;
vector<int>total;
if (size1 + size2 < k)return total;
for (int i = 0; i <= k; i++){//取num1中的第i个数
if (!(i <= size1&&k - i <= size2))continue;
if (i == 0)re = r2[k - i];
else re = merge(i, r1[i], k - i, r2[k - i]);
if (total.size() == 0)total = re;
else{
for (int i = 0; i < k; i++){
if (total[i] == re[i])continue;
else if (total[i]>re[i])break;
else total = re;
}
}
}
return total;
}
};
运行结果:
Submission Result: Accepted More Details
Share your acceptance!
思路分析:
1. 首先解决在单个数组中,如何求出由n个数构成的最大值,这个时候利用动态规划思想
假设我们的数组元素有num={6,3,5,4,1,2},这时要求出n=6时数组元素所能构成的最大元素,则很明显是数组本身;
n=5时,我们要剔除1,则此时有{6,3,5,4,2}
n=4,有{6,3,5,4}
依次递归下去;求解的时候从第二个数开始,如果它比它前面的数大,则删除它前面的一个数;否则删除最后一个数;
2, 要求两个数组组成的最大的数,对于num1和num2来说,等于先从num1中选取i个数然后再从num2中选取k-i个数,然后按贪心原则分别从
这两个数组中取数!!!!
这里要十分注意的一点的是,我们在两个数组里分别取数遵循的原则不是取数字最大的i个数,而是能构成最大数值的i个数,假设:
我们在A数组中取的构成最大值的3个数是:{a1,a2,a3}
在数组B中,取得的构成的最大值的4个数是:{b1,b2,b3,b4}
那么对于A的三个数来说,无论B中的几个数如何插入到A中,{b1,b2,a1,b3,a2,b4,a3}在序列值固定的情况下,A中三个元素的贡献值为:a1*10000+a2*100*a3,如果
将a1,a2,a3中的任何一个值替换成A数组中其它的数,则其贡献值肯定减少!!!!所以一定是取能够成最大数值的i个数,而不是从左到右取最大的i个数字!!!!