algo-en
  • Introduction
  • I. Dynamic Programming
    • Dynamic Programming in Details
    • Classic DP: Edit Distance
    • Classic DP: Super Egg
    • Classic DP: Super Egg(Advanced Solution)
    • Class DP: Longest Common Subsequence
    • Classis DP: Game Problems
    • Regular Expression
    • The Strategies of Subsequence Problem
    • Greedy: Interval Scheduling
    • 4 Keys Keyboard
    • What is DP Optimal Substructure
    • Longest Increasing Subsequence
    • KMP Algorithm In Detail
    • House Robber Problems
    • Stock Buy and Sell Problems
  • II. Data Structure
    • Binary Heap and Priority Queue
    • LRU Cache Strategy in Detail
    • Collections of Binary Search Operations
    • Special Data Structure: Monotonic Stack
    • Special Data Structure: Monotonic Stack
    • Design Twitter
    • Reverse Part of Linked List via Recursion
    • What's the Best Algo Book
    • Queue Implement Stack/Stack implement Queue
    • Framework for learning data structures and algorithms
  • III. Algorithmic thinking
    • My Way to Learn Algorithm
    • The Framework for Backtracking Algorithm
    • Binary Search in Detail
    • The Tech of Double Pointer
    • The Key Concept of TwoSum Problems
    • Divide Complicated Problem: Implement a Calculator
    • Prefix Sum Skill
    • FloodFill Algorithm in Detail
    • Interval Scheduling: Interval Merging
    • Interval Scheduling: Intersections of Intervals
    • String Multiplication
    • Pancake Soring Algorithm
    • Sliding Window Algorithm
    • Some Useful Bit Manipulations
    • Russian Doll Envelopes Problem
    • Recursion In Detail
    • Backtracking Solve Subset/Permutation/Combination
    • Several counter-intuitive Probability Problems
    • Shuffle Algorithm
  • IV. High Frequency Interview Problem
    • How to Implement LRU Cache
    • How to Find Prime Number Efficiently
    • How to Calculate Minimium Edit Distance
    • How to Solve Drop Water Problem
    • How to Remove Duplicate From Sorted Sequence
    • How to Find Longest Palindromic Substring
    • How to Reverse Linked List in K Group
    • How to Check the Validation of Parenthesis
    • How to Find Missing Element
    • How to Pick Elements From a Arbitrary Sequence
    • How to use Binary Search
    • How to Scheduling Seats
    • Union-Find Algorithm in Detail
    • Union-Find Application
    • Find Subsequence With Binary Search
    • Problems can be solved by one line
    • How to Find Duplicate and Missing Element
    • How to Check Palindromic LinkedList
  • V. Common Knowledge
    • Difference Between Process and Thread in Linux
    • You Must Know About Linux Shell
    • You Must Know About Cookie and Session
    • Cryptology Algorithm
    • Some Good Online Pratice Platforms
Powered by GitBook
On this page
  • 1. Overview
  • 2. Solution
  • 3. Conclusion

Was this helpful?

  1. III. Algorithmic thinking

Russian Doll Envelopes Problem

PreviousSome Useful Bit ManipulationsNextRecursion In Detail

Last updated 5 years ago

Was this helpful?

Translator:

Author:

Many algorithm problems require sorting skills. The difficulty is not in the sort itself, but ingenious sorting for preprocessing, transforming the algorithm problems, and laying the foundation for subsequent operations.

The russian doll envelopes needs to be sorted according to specific rules, and then converted into a . You can use the trick of previous text to solve the problem.

1. Overview

Russian doll envelopes is a very interesting and often occurring problem in life. Let's look at the problem first:

You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envelope can fit into another if and only if both the width and height of one envelope is greater than the width and height of the other envelope.

What is the maximum number of envelopes can you Russian doll? (put one inside other)

Note:

Rotation is not allowed.

Example:


Input: [[5,4],[6,4],[6,7],[2,3]]
Output: 3 
Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).

This question is actually a variant of Longes Increasing Subsequence(LIS), because it is clear that each legal nesting is a large set of small, which is equivalent to finding a longest increasing subsequence , and its length is the maximum number of envelopes that can be nested.

But the difficulty is that the standard LIS algorithm can only find the longest subsequence in the array, and our envelope is represented by a two-dimensional number pair like (w, h). How can we apply the LIS algorithm?

The reader may calculate the area by w × h, and then perform the standard LIS algorithm on the area. However, if you think about it a little, you will find that this is not possible. For example, 1 × 10 is greater than3 × 3, but obviously such two envelopes cannot be nested inside each other.

2. Solution

The solution to this problem is relatively clever:

First sort the width w in ascending order. If you encounter the same situation withw, sort in descending order by height h. Then use all h as an array, and calculate the length of LIS on this array is the answer.

Draw a picture to understand, first sort these number pairs:

Then look for the longest increasing subsequence on h:

This subsequence is the optimal nesting scheme.

The key to this solution is that for pairs of the same width w, the heighth is sorted in descending order. Because two envelopes of the same width cannot contain each other, reverse ordering guarantees that at most one of the pairs of the same w is selected.

The code as follow:

// envelopes = [[w, h], [w, h]...]
public int maxEnvelopes(int[][] envelopes) {
    int n = envelopes.length;
    // sort by ascending width, and sort by descending height if the width are the same
    Arrays.sort(envelopes, new Comparator<int[]>() 
    {
        public int compare(int[] a, int[] b) {
            return a[0] == b[0] ? 
                b[1] - a[1] : a[0] - b[0];
        }
    });
    // find LIS on the height array
    int[] height = new int[n];
    for (int i = 0; i < n; i++)
        height[i] = envelopes[i][1];

    return lengthOfLIS(height);
}

Regarding the search method for the longest increasing subsequence, the dynamic programming solution was introduced in detail in the previous article, and the binary search solution was explained using a poker game. This article will not expand and directly apply the algorithm template:

/* returns the length of LIS in nums */
public int lengthOfLIS(int[] nums) {
    int piles = 0, n = nums.length;
    int[] top = new int[n];
    for (int i = 0; i < n; i++) {
        // playing card to process
        int poker = nums[i];
        int left = 0, right = piles;
        // position to insert for binary search
        while (left < right) {
            int mid = (left + right) / 2;
            if (top[mid] >= poker)
                right = mid;
            else
                left = mid + 1;
        }
        if (left == piles) piles++;
        // put this playing cart on top of the pile
        top[left] = poker;
    }
    // the number of cards is the LIS length
    return piles;
}

For clarity, I divided the code into two functions. You can also merge them to save space in the height array.

The time complexity of this algorithm is O(NlogN), because sorting and calculating LIS each takes O(NlogN).

The space complexity is O(N), because a top array is needed in the function to calculate LIS.

3. Conclusion

This problem is a hard-level problem, and its difficult lies in sorting. The problem is transformed into a standard LIS problem after correct sorting, which is easy to solve.

In fact, this problem can also be extended to three dimensions. For example, instead of letting you nest envelopes, you need to nest boxes. Each box has three dimensions: length, width, and height. Can you count how many boxes can be nested?

We may think so, first find the nested sequence according to the idea of envelope nesting in the first two dimensions(length and width), and finally find LIS in the third dimension(height) of this sequence, and we should be able to calculate the answer.

In fact, this idea is wrong. This type of problem is called a partial order problem. Ascending to three dimensions will greatly increase the difficulty. An advanced data structure called Binary Index Tree is needed, and interested readers can search by themselves.

There are many algorithmic problems that need to be sorted and processed, and author is collating and summarizing. Hope this article is helpful to you.

Dong Wang
labuladong
Longest Incremental Subsequence Problem
Binary Search Detailed Explanation