646. 最长数对链
- 先从题中找关键点
- 数对(a,b)中,b > a
- 数对链(a, b) (c, d)中,c > b
- 答案是找最长的数对链的长度
- 可以先尝试将所有数对排序,看是否能找到最长的数对链。
- 可以分类讨论,将数对按第一个数排序后,在数对(a, b) (c, d)中
- 若c > b,那正好形成数对链
- 若d < b,在最长数对链中(c, d)可以取代(a, b)
- 因此用stack或list结构存储最长数对链,遍历排序后的数对
- 先看是否c > b,大于就放入数对链中;
- 若不大于,则看是否可以取代,也就是 d < b
- 若可以取代则取代,不行则继续遍历
- 如此一次遍历就可以找到最长的数对链
- 时间复杂度:排序用了O(nlogn),后面再遍历一次O(n),所以是O(nlogn)
- 也可以用DP来做
- 将数对按第一个数排序后
- 用
int[] dp记录以每个数对结尾的数对链的长度,dp[i]的长度就是前一个满足条件的dp[j]+1 - 时间复杂度:O(n^2)
approach 1,排序+贪心
class Solution {
public int findLongestChain(int[][] pairs) {
Arrays.sort(pairs, (a, b) -> {
if (a[0] == b[0]) {
return a[1] - b[1];
} else {
return a[0] - b[0];
}
});
Stack<int[]> stack = new Stack<>();
for (int[] p : pairs) {
if (stack.empty()) {
stack.push(p);
continue;
}
int[] peek = stack.peek();
if (p[0] > peek[1]) {
stack.push(p);
} else if (peek[1] > p[1]) {
stack.pop();
stack.push(p);
}
}
return stack.size();
}
}
approach 2,排序+DP
class Solution {
public int findLongestChain(int[][] pairs) {
Arrays.sort(pairs, (a, b) -> a[0] - b[0]);
int n = pairs.length;
int[] dp = new int[n];
int res = 1;
for (int i = 0; i < n; i++) {
dp[i] = 1;
for (int j = i - 1; j >= 0; j--) {
if (pairs[i][0] > pairs[j][1]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
res = Math.max(res, dp[i]);
}
return res;
}
}