题目链接:https://leetcode.com/problems/russian-doll-envelopes/
每个洋娃娃有两个维度,长和宽,只有两者都比另外一个洋娃娃的对应维度大,才能够装另外一个。
这个问题其实就是LIS。
朴素的做法直接排序之后O(n^2)去dp一下,那么既然问题可以规约到LIS,必然是可以O(nlogn)处理的。
排序的时候,一个维度比如w,按照从小到大排,这个是第一顺序,另一个维度h按照从大到小排,这个是第二顺序。
原因就是w相同的娃娃,不能嵌套,所以h在w相同情况下,按照从大到小排,可以保证不会出现w相同娃娃互相嵌套的情况。
那么这个时候问题的答案其实就是所有的h值组成的数列的LIS大小了。
Java中,我没找到类似于C++的可以在数组上做lower_bound的API,所以只能手写一个lower_bound了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 public class Solution { 2 public int maxEnvelopes(int[][] envelopes) { 3 Arrays.sort(envelopes, (x, y) -> (x[0] == y[0] ? y[1] - x[1] : x[0] - y[0])); 4 int n = envelopes.length; 5 int[] dp = new int[n]; 6 Arrays.fill(dp, Integer.MAX_VALUE); 7 for (int i = 0; i < n; i++) { 8 int index = lower_bound(dp, envelopes[i][1]); 9 dp[index] = envelopes[i][1]; 10 } 11 return lower_bound(dp, Integer.MAX_VALUE); 12 } 13 14 private int lower_bound(int[] dp, int target) { 15 int n = dp.length; 16 int l = 0, r = n; 17 while (l < r) { 18 int m = l + r >>> 1; 19 if (dp[m] < target) { 20 l = m + 1; 21 } else { 22 r = m; 23 } 24 } 25 return l; 26 } 27 }
-----------------------------------------------------------------------------------------------------------------------------
话说,我觉得写LeetCode的题解好像看的人比CF、TC或者其他一些OJ的人多不知道多少个数量级哎。