321. 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 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]

思路:

从数组nums1取i个元素,从数组nums2中k-i个元素,再将两者组合,取得最大的组合整数即可。

i的范围为:Math.max(0, k - nums2.length),因为有可能所有元素都从nums2中取, 如

nums1 = [1, 2, 3]

nums2 = [9, 8, 7, 6]

k = 3

也有可能至少需要从nums1中取k-nums2.length个元素,比如Example2,至少要从nums1中取2个元素。这是因为nums2中元素较少,同时k又相对nums2元素个数多的时候。

判断两个数组大小的时候有些细节需要注意,比如

nums1 = [3, 8]

nums2 = [3]

k = 3

应该理解为nums1 > nums2,因为需要先取nums1中的3, 才能构成最大值383,否则如果先取nums2中的3,则变成338了。

程序如下所示:

class Solution {
    public int[] maxNumber(int[] nums1, int[] nums2, int k) {
        int[] ans = new int[k];
        for (int i = Math.max(0, k - nums2.length); i <= k&&i <= nums1.length; ++ i){
            int[] ret = mergeArray(maxArray(nums1, i), maxArray(nums2, k - i), k);
            ans = isGreater(ans, 0, ret, 0)?ans:ret;
        }
        return ans;
    }
    
    public int[] mergeArray(int[] nums1, int[] nums2, int k){
        int[] ret = new int[k];
        for (int i = 0, j = 0, r = 0; r < k; ++r){
            ret[r] = isGreater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];
        }
        return ret;       
    }
    
    public boolean isGreater(int[] nums1, int i, int[] nums2, int j){
        while (i < nums1.length&&j < nums2.length&&nums1[i] == nums2[j]){
            i ++;
            j ++;
        }
        return j == nums2.length || (i < nums1.length && nums1[i] > nums2[j]);
    }
    
    public int[] maxArray(int[] nums, int k){
        int[] ret = new int[k];
        int index = 0;
        for (int i = 0; i < nums.length; ++ i){
            while (nums.length-i+index > k&&index > 0&&ret[index-1] < nums[i]){
                index --;
            }
            if (index < k){
                ret[index++] = nums[i];
            }
        }
        return ret;
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值