> For the complete documentation index, see [llms.txt](https://protegejj.gitbook.io/algorithm-practice/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://protegejj.gitbook.io/algorithm-practice/leetcode/dynamic-programming/lis/354-russian-doll-envelopes.md).

# 354 Russian Doll Envelopes

## 354. [Russian Doll Envelopes](https://leetcode.com/problems/russian-doll-envelopes/description/)

## 1. Question

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)

**Example:**\
Given envelopes =`[[5,4],[6,4],[6,7],[2,3]]`, the maximum number of envelopes you can Russian doll is`3`(\[2,3] => \[5,4] => \[6,7]).

## 2. Implementation

**(1) Sorting + DP**

```java
class Solution {
    public int maxEnvelopes(int[][] envelopes) {
        if (envelopes == null || envelopes.length == 0) {
            return 0;
        }

        Arrays.sort(envelopes, new Comparator<int[]>() {
           @Override
            public int compare(int[] a, int b[]) {
                if (a[0] == b[0]) {
                    return b[1] - a[1];
                }
                else {
                    return a[0] - b[0];
                }
            }
        });

        int n = envelopes.length;
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        int maxLen = 1;

        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (envelopes[j][1] < envelopes[i][1] && dp[j] + 1 > dp[i]) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLen = Math.max(maxLen, dp[i]);
        }
        return maxLen;
    }
}
```

**(2) Sorting + Binary Search优化**

在查找最长递增序列时，我们可以用Binary Search进行优化，Binary Search可以查找新的序列的插入位置，思想类似于leetcode 35

```java
class Solution {
    public int maxEnvelopes(int[][] envelopes) {
        if (envelopes == null || envelopes.length == 0) {
            return 0;
        }

        int n = envelopes.length;

        Arrays.sort(envelopes, new Comparator<int[]>() {
            public int compare(int[] a, int[] b) {
                if (a[0] == b[0]) {
                    return b[1] - a[1];
                }
                else {
                    return a[0] - b[0];
                }
            }
        });

        int index = 0, len = 0;
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            int height = envelopes[i][1];
            index = binarySearch(arr, 0, len, height);

            if (index == len) {
                ++len;
            }
            arr[index] = height;
        }
        return len;
    }

    public int binarySearch(int[] arr, int start, int end, int target) {
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;

            if (arr[mid] < target) {
                start = mid + 1;
            }
            else {
                end = mid;
            }
        }
        return arr[start] >= target ? start : end;
    }
}
```

## 3. Time & Space Complexity

**Sorting + DP:**&#x65F6;间复杂度O(nlogn + n^2), n为envelope的个数, 空间复杂度O(n)

**Sorting + Binary Search优化:** 时间复杂度O(nlogn + nlogn), 空间复杂度O(n)
