Leetcode 321. Create Maximum Number

来源:互联网 发布:英语文献翻译软件 编辑:程序博客网 时间:2024/05/17 03:25

问题描述:

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.

问题分析:
问题要求从两个数组中选择k个数字,使得新组成数字是最大的,并且保证选择的数字不改变在原来数组中的相对顺序。
问题可以转化为两个子问题:

1、从数组nums中挑出t个数,在保持元素相对顺序不变的情况下使得挑出的数字最大     2、在保持元素相对顺序不变的前提下,将两个数组合并成一个数组,使得合并后的数组最大

原问题可以转化为:遍历两个数组挑选元素的个数,分别求出当前策略下2个问题的解,然后返回最大结果。
子问题1:可以借助栈来实现
遍历nums
<1>如果栈顶元素比当前元素小,弹出栈顶元素,直到1、栈空,2、剩余nums中的元素不足以填满t
<2>如果栈里元素不够t,则将当前元素压入栈中。
子问题2:与归并排序类似
分别比较两数组剩余数组的大小,将大的那个数组的当前数填入新数组。

这里需要注意比较的是剩余数组的大小,而非当前元素,因为当前元素相等时需要比较后面的元素,知道不相等,取比较大的那个数组中的当前元素

参考代码如下:

    public int[] maxNumber(int[] nums1, int[] nums2, int k) {        int n=nums1.length;        int m=nums2.length;        int[] result=null;        for(int i=0;i<=n&&i<=k;i++){            int j=k-i;            if(j>=0&&j<=m&&j<=k){                result=max(result,merge(getMax(nums1,i),getMax(nums2,j)));            }        }        return result;    }    public int[]max(int[]nums1,int[]nums2){        if(nums1==null)            return nums2;        int n=nums1.length;        for(int i=0;i<n;i++){            if(nums1[i]<nums2[i])                return nums2;            if(nums1[i]>nums2[i])                return nums1;        }        return nums1;    }    public int[]getMax(int[]nums,int len){        if(len==0)            return null;        int n=nums.length;        int[]temp=new int[n];        int ri=0;        for(int i=0;i<n;i++){            while(ri>0&&ri+n-i>len&&temp[ri-1]<nums[i])                ri--;            if(ri<len)                temp[ri++]=nums[i];        }        int[]result=new int[len];        for(int i=0;i<len;i++){            result[i]=temp[i];        }        return result;    }    public boolean greater(int[]nums1,int i,int[] nums2,int j){        int n=nums1.length;        int m=nums2.length;        while(i<n&&j<m){            if(nums1[i]<nums2[j])                return false;            else if(nums1[i]>nums2[j])                return true;            //相等            i++;            j++;        }        if(i<n)            return true;        else            return false;    }    public int[]merge(int[]nums1,int[] nums2){        if(nums1==null)            return nums2;        if(nums2==null)            return nums1;        int n=nums1.length;        int m=nums2.length;        int[]result=new int[n+m];        int i=0,j=0,k=0;        while(i<n&&j<m){            if(greater(nums1,i,nums2,j)){                result[k++]=nums1[i++];            }            else{                result[k++]=nums2[j++];            }        }        while(i<n)            result[k++]=nums1[i++];        while(j<m)            result[k++]=nums2[j++];        return result;    }

参考链接:
http://bookshadow.com/weblog/2015/12/24/leetcode-create-maximum-number/
http://www.cnblogs.com/CarryPotMan/p/5384172.html

原创粉丝点击