Create Maximum Number

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 kdigits.

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]);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值