LeetCode-354-俄罗斯套娃信封问题
字节跳动 2021秋招8.8笔试题
题目
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
说明:
不允许旋转信封。
示例: 输入: envelopes = [[5,4],[6,4],[6,7],[2,3]] 输出: 3 解释: 最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。
思路
将二维数组进行排序,排序规则如下:按照一维数据上升二维数据下降。
则示例中的输入成为
[2,3] [5,4] [6,7] [6,4]
只需要在二维数据列中寻找最长上升子序列即可。
1 class Solution { 2 public static int maxEnvelopes(int[][] envelopes) { 3 4 if(envelopes.length == 0 ) return 0; 5 // 按照一维数据上升二维数据下降对输入进行排序 6 Arrays.sort(envelopes, new Comparator<int[]>() { 7 public int compare(int[] arr1, int[] arr2) { 8 if (arr1[0] == arr2[0]) { 9 return arr2[1] - arr1[1]; 10 } else { 11 return arr1[0] - arr2[0]; 12 } 13 } 14 }); 15 16 int[] secondDim = new int[envelopes.length]; 17 for (int i = 0; i < envelopes.length; ++i) secondDim[i] = envelopes[i][1]; 18 return lengthOfLIS(secondDim); 19 20 21 22 } 23 24 /** 25 * @param secondDim 26 * @return 27 */ 28 private static int lengthOfLIS(int[] secondDim) { 29 // TODO Auto-generated method stub 30 31 int[] dp = new int[secondDim.length]; 32 33 dp[0] = 1; 34 35 for(int i = 1;i<secondDim.length;i++) { 36 int now = secondDim[i]; 37 int index = 0; 38 int max = Integer.MIN_VALUE; 39 for(int j=0;j<i;j++) { 40 41 int pri = secondDim[j]; 42 if(now > pri && dp[j] > max) { 43 index = j; 44 max = dp[j]; 45 } 46 47 } 48 if(max == Integer.MIN_VALUE) dp[i] = 1; 49 else dp[i] = max + 1; 50 51 } 52 53 Arrays.sort(dp); 54 55 return dp[dp.length-1]; 56 } 57 }