354 Russian Doll Envelopes

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 is3([2,3] => [5,4] => [6,7]).

2. Implementation

(1) Sorting + DP

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

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:时间复杂度O(nlogn + n^2), n为envelope的个数, 空间复杂度O(n)

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

Last updated