LeetCode-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]

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

Analysis:

The solution is inspired by @dietpepsi and @chellya based on the following posts:
[1]: https://discuss.leetcode.com/topic/32272/share-my-greedy-solution
[2]: https://discuss.leetcode.com/topic/36805/c-16ms-fastest-beats-97

I used optimization introduced in [2] and the merge method introduced in [1].

To summarize:

  1. We can find the max number with length X (named maxNumLenX) from an array nums using stack method. [1][2]
  2. Based on maxNumLenX, we can find max numbers with length of X-1, X-2, ..., 1. [2].
  3. Based on 1. and 2., we can solve the problem like this:
    a. Find maxNum2 with max possible length from nums2.
    b. Find all max numbers with less length to the min possible length.
    c. Try maxNum1 with every possible length, starting from the max
    possible length; Directly fetch the corresponding maxNum2
    (maxNum1.length + maxNum2.length ==k), merge them and generate the
    results.
    d. When generating maxNum1 with length X in the loop, we can generate it from maxNum1 with length X+1.

NOTE:

DP solution is like this:

dp[i][j][k]: the max number with length k, using nums1[0..i] and nums2[0...j].

dp[i][j][k] = max{ dp[i-1][j][k], dp[i][j-1][k], (nums1[i]+dp[i-1][j][k-1]), (nums2[j]+dp[i][j-1][k-1])}.

While the greedy solution is really hard to figure out in a short time, the DP solution is much easier to derive.

Solution:

public class Solution {
    public int[] maxNumber(int[] nums1, int[] nums2, int k) {
        if (k==0) return new int[k];
        if (nums1.length==0){
            return getMaxNumberFromNums(nums2,k);
        }
        if (nums2.length==0){
            return getMaxNumberFromNums(nums1,k);
        }

        // Generates the max number of nums2 with the max possible length.
        int[] maxNum2 = getMaxNumberFromNums(nums2,Math.min(nums2.length,k));

        // Generates the max number of nums2 of each possible length.
        Deque<int[]> maxNums2 = getMaxNumsForAllLenth(maxNum2,Math.max(k-nums1.length, 0));

        int[] maxNum1 = getMaxNumberFromNums(nums1,Math.min(nums1.length,k));
        int[] res = new int[k];
        for (int len1 = Math.min(nums1.length,k);len1>=Math.max(k-nums2.length,0);len1--){
            if (len1 < Math.min(nums1.length,k)){
                maxNum1 = getMaxNumWithOneLessLen(maxNum1);
            }
            maxNum2 = maxNums2.pollFirst();
            res = getNewMaxNumber(res,maxNum1,maxNum2);
        }
        return res;
    }

    // Get max number with length of maxNumLen from nums.
    public int[] getMaxNumberFromNums(int[] nums, int maxNumLen){
        int[] maxNum = new int[maxNumLen];
        int len = nums.length;
        int end = 0;
        for (int i=0;i<len;i++){
            while (end >= 1 && maxNum[end-1] < nums[i] && len - i > maxNumLen - end){
                end--;
            }
            if (end < maxNumLen) maxNum[end++] = nums[i];
        }
        return maxNum;
    }

    // Get max numbers with length of maxNum.length, maxNum.length-1, ..., minLen, based on maxNum.
    public Deque<int[]> getMaxNumsForAllLenth(int[] maxNum, int minLen){
        Deque<int[]> maxNums = new LinkedList<int[]>();
        maxNums.add(maxNum);
        while (maxNum.length>minLen){
            int[] nextNum = getMaxNumWithOneLessLen(maxNum);
            maxNums.addFirst(nextNum);
            maxNum = nextNum;
        }
        return maxNums;
    }

    // Get the max number with length of  maxNum.length-1 from maxNum.
    public int[] getMaxNumWithOneLessLen(int[] maxNum){
        int len = maxNum.length, end = 0;
        int[] nextNum = new int[len-1];
        boolean deleted = false;
        for (int i=0;i<len;i++){
            if (end >= len-1) break;
            if ((i==len-1 || maxNum[i] >= maxNum[i+1]) || deleted){
                nextNum[end++] = maxNum[i];
            } else {
                deleted = true;
            }
        }
        return nextNum;
    }

    // Merge part1 and part2 into a new max number, substitute the old one if the new one is larger.
    public int[] getNewMaxNumber(int[] maxNum, int[] part1, int[] part2){
        int[] newNum = new int[maxNum.length];
        int p1 = 0, p2 = 0, index = 0;
        boolean newNumLarger = false;
        while (p1 < part1.length || p2 < part2.length){
            newNum[index] = (greater(part1,p1,part2,p2)) ? part1[p1++] : part2[p2++];

            // Early termination, if we find new number is less than the existing one.
            if (maxNum[index] > newNum[index] && !newNumLarger){
                return maxNum;
            } else if (maxNum[index] < newNum[index]){
                newNumLarger = true;
            }
            index++;
        }
        return newNum;
    }

    // This is function is important. When merging two parts into the max number, we need address the case part1[p1] == part2[p2].
    public boolean greater(int[] part1, int p1, int[] part2, int p2){
        while (p1<part1.length && p2<part2.length && part1[p1]==part2[p2]){
            p1++;
            p2++;
        }

        return p2==part2.length || (p1 < part1.length && part1[p1] > part2[p2]);
    }
}
时间: 2024-10-05 09:33:47

LeetCode-Create Maximum Number的相关文章

[LintCode] 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 digit

Leetcode 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 + nfrom digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k digits

LeetCode Third Maximum Number

原题链接在这里:https://leetcode.com/problems/third-maximum-number/#/description 题目: Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). Exa

321. Create Maximum Number (c++ ——&gt; lexicographical_compare)

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 digit

[LeetCode] Third Maximum Number 第三大的数

Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). Example 1: Input: [3, 2, 1] Output: 1 Explanation: The third maximum is 1. Examp

Create Maximum Number

1 public class Solution { 2 public int[] maxNumber(int[] nums1, int[] nums2, int k) { 3 int[] result = new int[k]; 4 5 for (int i = Math.max(0, k - nums2.length); i <= k && i <= nums1.length; i++) { 6 int[] candidate = merge(getMaxArray(nums

leetcode_321 Create Maximum Number

题目分析: 给定两个长度分别为m和n的数组,数组元素为0-9,每个数组元素代表一个数字.从这两个数组中选出一些数字,组成一个数组,是这个数组中的数尽可能大,其长度k <= m + n.要求数组中选出的元素的相对顺序与原数组保持一致.最终返回一个包含k个数字的数组. 解题思路: 1)分别从nums1(长度为m)和nums2(长度为n)中挑选出i(max(0, k - n) <= i <= min(m, k) 和k-i个数,在保持挑选数组的元素相对顺序不变的情况下,使选出的子数组最大化,主要

LeetCode 414. Third Maximum Number (第三大的数)

Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). Example 1: Input: [3, 2, 1] Output: 1 Explanation: The third maximum is 1. Examp

[LeetCode OJ] Max Points on a Line—Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

//定义二维平面上的点struct Point { int x; int y; Point(int a=0, int b=0):x(a),y(b){} }; bool operator==(const Point& left, const Point& right) { return (left.x==right.x && left.y==right.y); } //求两个点连接成的直线所对应的斜率 double line_equation(const Point&

(leetcode题解)Third Maximum Number

Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). Example 1: Input: [3, 2, 1] Output: 1 Explanation: The third maximum is 1. Examp