321. Create Maximum Number 找到两个数组中能合并的k个的最大数

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]


解答:

题意:根据两个数组,从中找到部分数组(原先位置序列不变),组合,得到新的数组且最大值
思路:要找到组合的值最大,肯定也要找从一个数组中找的i个数最大,从另一个数组中找的k-i个数组成的数最大。那么i从1~len遍历就行
剩下的问题就是,对于一个数组,怎么去除一个数使得剩下的数最大
1.用栈,遇到大的数就将栈中原来的数取出,再将大的数放入,遇到小的数放进去(对于一个数组取k个数)
2.就是把递增到达后的数前面的数一个个删除,得到每个长度时最大的数(用于对于两个数组进行合并的情况)


这里就是用栈来解决得到最大数
In short we can first solve 2 simpler problem


Create the maximum number of one array
Create the maximum number of two array using all of their digits.


合并的时候注意:
不能用正常合并的思路,否则出现如下错误:
6 7
6 0 4
--> 6 6 7 0 4
正确:6 7 6 0 4 
应该是,当遇到两个数相同时,应该判断这个数后面的两个对应的数(7 0 )的大小


代码:

class Solution {
public:
//从数组中找到k个最大的数,用栈的思想
vector<int> getmax(vector<int>& nums, int k){
    vector<int>res(k,0);
    int i = 0, j = 0; //i代表nums的位置,j代表res的位置
    int n = nums.size();
    for(;i < nums.size(); i++){
        while(n-i+j > k && j > 0 && res[j-1] < nums[i]) --j; //注意:这里的n-i+j的作用是防止当遍历到nums的最后k-j个位置的数时,不用再弹出了,直接赋值给res就行
        if(j < k) res[j++] = nums[i];
    }
    return res;
}

vector<int> merge(vector<int>res1, vector<int>res2){
    int i = 0, j = 0, k = 0;
    vector<int>res(res1.size() + res2.size(), 0);
    while(i < res1.size() && j < res2.size()){
        if(greaters(res1, i, res2, j))
            res[k++] = res1[i++];
        else
            res[k++] = res2[j++];
    }
    while(i < res1.size())
        res[k++] = res1[i++];
    while(j < res2.size())
        res[k++] = res2[j++];
    return res;
}

bool greaters(vector<int>res, int i, vector<int>ans, int j){
    while(i < res.size() && j < ans.size() && res[i] ==ans[j]){
        ++i;
        ++j;
    }
    return (j == ans.size() || (i < res.size() && j < ans.size() && res[i] > ans[j]));
    
}

vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
    int len1 = nums1.size();
    int len2 = nums2.size();
    vector<int>ans(k, 0);
    for(int i = max(0, k - len2); i <= min(len1, k); i++){ //取的个数
        vector<int> nums_max1 = getmax(nums1, i);
        vector<int> nums_max2 = getmax(nums2, k-i);
        vector<int>res = merge(nums_max1, nums_max2);
        if(greaters(res, 0, ans, 0))  ans = res;
    }
    return ans;
}
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值