解题思路
刚看到这题时我也是一脸懵逼
但是看了下大神给出的题解后便豁然开朗了
总体思路分为两步
一.对原始的数据按照w升序的基础上w降序的方式进行排序
envelopes[w][h]
例如对[[5,4],[6,4],[6,7],[2,3]]排序后
结果为[2, 3][5, 4][6, 7][6, 4]
这样做的目的是保证了W处于上升序列的同时 如果两个信封宽度相同 我们选择到H大的那一个
二.根据已经排好序的数组 根据H来找到最长上升子序长度
我也是刚刚学会Lis的算法
通俗来讲基本如下:
维护一个Lis数组 其中保存的数代表的就是当前这个数的前方构成的最长上升子序长度
从数组中的第二个数字开始循环不断更新找到这个数前面的最长上升子序
int[] Lis = new int[n];
int[] flag = new int[n];
Lis[0]=1;
for (int i = 1;i<n;i++){
for (int j = 0;j<i;j++){
int m = 1;
if (flag[i]>flag[j]){
m = Math.max(m,Lis[j]+1);
}
Lis[i]= Math.max(m,Lis[i]);
}
}
代码
class Solution {
public int maxEnvelopes(int[][] envelopes) {
int n = envelopes.length;
if(n==0){
return 0;
}
/*
对原始数据进行初步排序
*/
Arrays.sort(envelopes, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
/*
o1[0]正序
o1[1]逆序
*/
if (o1[0]>o2[0]) return 1;
else if (o1[0]==o2[0]){
if (o1[1]<o2[1]){
return 1;
}else if (o1[1]==o2[1]){
return 0;
}
return -1;
}
return -1;
}
});
/*
求出最长上升子序LIS长度
*/
int[] Lis = new int[n];
int[] flag = new int[n];
for (int i = 0;i<n;i++){
flag[i]=envelopes[i][1];
}
Lis[0]=1;
for (int i = 1;i<n;i++){
for (int j = 0;j<i;j++){
int m = 1;
if (flag[i]>flag[j]){
m = Math.max(m,Lis[j]+1);
}
Lis[i]= Math.max(m,Lis[i]);
}
}
Arrays.sort(Lis);
return Lis[n-1];
}
}