Start learning free

LESSON 469 OF 671 · STACK

Create Maximum Number in Java with Time Complexity Analysis

Practice O(n) Read the full explanation

You get two arrays of digits, nums1 and nums2. Each digit is from 0 to 9. You also get a number k.

Pick k digits in total from the two lists. Line them up to make the largest possible k-digit number. Return its digits as an array.

Digits from the same list must keep their order from that list. Apart from that, digits from the two lists can mix in any way.

 

Example 1:

Input: nums1 = [5, 2, 8], nums2 = [7, 1, 6, 3], k = 4
Output: [8, 7, 6, 3]
Explanation: Take the 8 from nums1.
Then take 7, 6 and 3 from nums2, in their order.

Example 2:

Input: nums1 = [4, 9], nums2 = [4, 1, 5], k = 5
Output: [4, 9, 4, 1, 5]
Explanation: All five digits are used.
Both lists start with 4.
Taking the 4 of nums1 first lets its 9 come second.
49415 is larger than 44915.

Example 3:

Input: nums1 = [1, 1], nums2 = [3, 0, 2], k = 2
Output: [3, 2]
Explanation: Both digits come from nums2.
Its 0 is skipped.

 

Constraints:

  • nums1 and nums2 each have 1 to 30 digits.
  • k is from 1 to the number of digits in both lists together.
STEP 1 OF 28
    Ctrl + Enter to check

    JAVA · STACK

    Create Maximum Number in Java, explained

    Understanding the Problem

    The core challenge of this problem is to create the largest possible number of length k by selecting digits from two given arrays while maintaining the relative order of digits from each array. This problem is significant in scenarios where we need to merge sequences optimally, such as in merging sorted lists or combining results from different sources.

    Potential pitfalls include not maintaining the relative order of digits from the same array and not considering all possible combinations of digits from both arrays.

    Approach

    To solve this problem, we need to consider the following steps:

    1. Generate the maximum number of length i from nums1 and length k-i from nums2 for all valid i.
    2. Merge these two numbers to form the largest possible number of length k.
    3. Compare all possible merged numbers and return the largest one.

    We will start with a naive approach and then optimize it.

    Naive Approach

    The naive approach would involve generating all possible combinations of digits from both arrays and then selecting the largest one. However, this approach is not feasible due to its high time complexity.

    Optimized Approach

    We can optimize the solution by breaking it down into smaller subproblems:

    1. Find the maximum number of a given length from a single array while maintaining the order of digits.
    2. Merge two sequences to form the largest possible sequence while maintaining the order of digits.

    Algorithm

    Step-by-Step Breakdown

    1. Max Number from Single Array: Use a stack to keep track of the maximum number of a given length from a single array.
    2. Merge Two Sequences: Compare elements from both sequences and merge them to form the largest possible sequence.
    3. Combine Results: Iterate through all possible lengths and combine the results to get the final answer.

    Code Implementation

    import java.util.*;
    
    public class CreateMaximumNumber {
        // Function to get the maximum number of length k from a single array
        private int[] maxNumberFromSingleArray(int[] nums, int k) {
            int n = nums.length;
            int[] result = new int[k];
            int j = 0;
            for (int i = 0; i < n; i++) {
                while (j > 0 && n - i + j > k && result[j - 1] < nums[i]) {
                    j--;
                }
                if (j < k) {
                    result[j++] = nums[i];
                }
            }
            return result;
        }
    
        // Function to merge two sequences to form the largest possible sequence
        private int[] merge(int[] nums1, int[] nums2, int k) {
            int[] result = new int[k];
            int i = 0, j = 0, r = 0;
            while (r < k) {
                if (greater(nums1, i, nums2, j)) {
                    result[r++] = nums1[i++];
                } else {
                    result[r++] = nums2[j++];
                }
            }
            return result;
        }
    
        // Helper function to compare two sequences
        private boolean greater(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]);
        }
    
        // Main function to create the maximum number of length k
        public int[] maxNumber(int[] nums1, int[] nums2, int k) {
            int m = nums1.length;
            int n = nums2.length;
            int[] maxResult = new int[k];
            for (int i = Math.max(0, k - n); i <= Math.min(k, m); i++) {
                int[] candidate = merge(maxNumberFromSingleArray(nums1, i), maxNumberFromSingleArray(nums2, k - i), k);
                if (greater(candidate, 0, maxResult, 0)) {
                    maxResult = candidate;
                }
            }
            return maxResult;
        }
    
        public static void main(String[] args) {
            CreateMaximumNumber solution = new CreateMaximumNumber();
            int[] nums1 = {3, 4, 6, 5};
            int[] nums2 = {9, 1, 2, 5, 8, 3};
            int k = 5;
            System.out.println(Arrays.toString(solution.maxNumber(nums1, nums2, k))); // Output: [9, 8, 6, 5, 3]
        }
    }
    

    Complexity Analysis

    The time complexity of the solution is O((m+n)^3) due to the nested loops and comparisons. The space complexity is O(k) for storing the result.

    Edge Cases

    Consider edge cases such as:

    • Arrays with all identical elements.
    • Arrays with different lengths.
    • Minimum and maximum values of k.

    Test these cases to ensure the solution handles them correctly.

    Testing

    To test the solution comprehensively, use a variety of test cases:

    • Simple cases with small arrays.
    • Complex cases with larger arrays.
    • Edge cases as mentioned above.

    Use testing frameworks like JUnit for automated testing.

    Thinking and Problem-Solving Tips

    When approaching such problems:

    • Break down the problem into smaller subproblems.
    • Think about the constraints and how they affect the solution.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    Understanding and solving this problem helps in developing skills for merging sequences optimally. Practice and explore further to master such problems.

    Additional Resources

    For further reading and practice:

    Keep going with Java650+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free