leetcode 321. 拼接最大数(单调栈)

给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。

求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。

说明: 请尽可能地优化你算法的时间和空间复杂度。

示例 1:

输入:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
输出:
[9, 8, 6, 5, 3]

代码

class Solution {
    public int[] maxNumber(int[] nums1, int[] nums2, int k) {

        int m=nums1.length,n=nums2.length;
        int[] res=new int[k];
        int s=Math.max(0,k-n),end=Math.min(k,m);
        for(int i=s;i<=end;i++)//遍历nums1和nums2不同取数情况返回的最大数组,返回最大的结果
        {
            int[] cur=merge(getMaxNumber(nums1, i),getMaxNumber(nums2, k-i));
            if(comp(cur,0,res,0))
                res=cur;
        }
        return res;

    }
    public boolean comp(int[] nums1,int p1 ,int[] nums2, int p2) {
//比较两个序列,如果前面元素都相同,则长度大的较大
        if(p2>=nums2.length) return true;
        if(p1>=nums1.length) return false;
        if(nums1[p1]>nums2[p2]) return true;
        if(nums1[p1]<nums2[p2]) return false;
        return comp(nums1, p1+1, nums2, p2+1);
    }
    public int[] merge(int[] nums1, int[] nums2) {
        int n=nums1.length,m=nums2.length;
        int cur=0,p1=0,p2=0;
        int []ret=new int[n+m];
        while (p1<n||p2<m)//合并两个数组
        {

            if(comp(nums1,p1,nums2,p2))
                ret[cur++]=nums1[p1++];
            else ret[cur++]=nums2[p2++];
        }
        return ret;

    }
    public int[] getMaxNumber(int[] nums1, int k) {//单调栈找出单个数组的最大排列
        int n=nums1.length,rem=n-k,top=-1;
        int[] stack=new int[k];
        for(int i=0;i<n;i++)
        {
            int cur=nums1[i];
            while (top>=0&&cur>stack[top]&&rem>0)
            {
                top--;
                rem--;
            }
            if(top<k-1)
                stack[++top]=cur;
            else rem--;//可删除的额度减一,当可删除的额度用尽,将不能再移除元素(为了保证返回数组的长度)
        }
        return stack;
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值