zoukankan      html  css  js  c++  java
  • LeetCode -- Create Maximum Number

    Question:

    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]

    Analysis:

    给出长度分别为m和n,由数字0-9构成的两个数组。给定一个k <= m + n,创建一个长度为k的最大数字,其中的数字由给出的两个数组决定,且同一个数组中数字的先后顺序要保持。

    思路:

    解决这个题目主要要解决两个子问题:

    1)每个数组中要拿出几个数字?

    2)拿出的这几个数字是什么?

    3)如何将两个基本有序的数组合并成一个?

    这样,分别从两个数组中取出一个子数组后,将两个子数组合并就可以了。

    所以我们首先解决第一个问题:

    • 每个数组中要拿出几个数字?方法只能是分情况讨论,然后遍历所有的组合可能;

    然后,解决第二个问题:

    • 拿出的这几个数字是什么?用一个栈保存当前结果。所有对于某个元素只有两种可能:一种是入栈,一种是更新。

    • 当 栈不空 && 后面还有足够的数字可以形成长度为k的数组 && 栈顶元素<当前元素,则应该用当前元素替换栈顶元素;

    • 其他情况下入栈就可以了。

    最后,合并两个子数组。

    • 类似两个链表merge的操作,每次选择两者中最大的一个即可。

    代码如下:

    public class Solution {
        public int[] maxNumber(int[] nums1, int[] nums2, int k) {
            if(k == 0) return new int[0];
            int m = nums1.length, n = nums2.length;
            if(m + n < k) return null;
            if(m + n == k) {
                int[] res = makeMerge(nums1, nums2, k);
                return res;
            }
            else { //m+n > k
                int max = m >= k ? k : m; //max means the max number of stack1
                int min = n >= k ? 0 : k-n;
                int[] res = new int[k];
                for(int i=0; i<k; i++)
                    res[i] = -0x7ffffffe;
                for(int i=min; i<=max; i++) {
                    int[] temp = makeMerge(getMax(nums1, i), getMax(nums2, k-i), k);
                    res = isGreater(res, 0, temp, 0) ? res : temp;
                }
                return res;
            }
        }
    
        private int[] makeMerge(int[] nums1, int[] nums2, int k) {
            int[] res = new int[k];
            if(k == 0) return res;
            int i = 0, j = 0;
            for(int t=0; t<k; t++ ) {
                res[t] = isGreater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];
            }
            return res;
        }
        private boolean isGreater(int[] nums1, int i, int[] nums2, int j) {
            // TODO Auto-generated method stub
            for(; i<nums1.length && j<nums2.length; i++, j++) {
                if(nums1[i] > nums2[j]) return true;
                if(nums1[i] < nums2[j]) return false;
            }
            return i != nums1.length;
        }
    
        private int[] getMax(int[] nums, int k) {
            if(k == 0) return new int[0];
            int[] res = new int[k];
            int i = 0;
            for(int j=0; j<nums.length; j++) {
                while(nums.length - j + i > k && i > 0 && res[i-1] < nums[j])
                    i--;
                if(i < k)
                    res[i++] = nums[j];
            }
            return res;
        }
        
    }
  • 相关阅读:
    20145215《Java程序设计》第4周学习总结
    20145215《Java程序设计》第3周学习总结
    20145215《Java程序设计》第2周学习总结
    关于开源中国的代码托管
    问卷调查
    2019年12月29日 回怼老王
    cnblogs今天挂了
    感悟别人的感悟——写在2020年前一天
    心情随笔_20191231
    js事件冒泡和捕捉
  • 原文地址:https://www.cnblogs.com/little-YTMM/p/5390678.html
Copyright © 2011-2022 走看看