题目:646. 最长数对链
方法一:动态规划dp,时间复杂度0(n^2)。
C++版本:
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
sort(pairs.begin(),pairs.end());
int n=pairs.size();
vector<int> f(n);
int mx=0;
for(int i=0;i<n;i++){
f[i]=1;
for(int j=i-1;j>=0;j--){
if(pairs[i][0]>pairs[j][1]) f[i]=max(f[i],f[j]+1);
}
mx=max(f[i],mx);
}
return mx;
}
};
JAVA版本:
class Solution {
public int findLongestChain(int[][] pairs) {
Arrays.sort(pairs,Comparator.comparingInt(a->a[0]));
int n=pairs.length;
int[] f=new int[n];
int mx=0;
for(int i=0;i<n;i++){
f[i]=1;
for(int j=i-1;j>=0;j--){
if(pairs[i][0]>pairs[j][1]) f[i]=Math.max(f[i],f[j]+1);
}
mx=Math.max(f[i],mx);
}
return mx;
}
}
Go版本:
func findLongestChain(pairs [][]int) int {
sort.Slice(pairs,func(i,j int) bool{
return pairs[i][0]<pairs[j][0]
})
n:=len(pairs)
f:=make([]int,n)
mx:=0
for i:=0;i<n;i++ {
f[i]=1
for j:=i-1;j>=0;j-- {
if pairs[i][0]>pairs[j][1] {
f[i]=max(f[i],f[j]+1)
}
}
mx=max(mx,f[i])
}
return mx
}
方法二:贪心+排序,时间复杂度0(nlogn)。
C++版本:
class Solution {
public:
typedef pair<int,int> PII;
int findLongestChain(vector<vector<int>>& pairs) {
//先确保第二个元素是升序排序
vector<PII> v;
for(auto x:pairs){
v.push_back({x[1],x[0]});
}
sort(v.begin(),v.end());
//ans:答案,mn:当前数对链的最小右边值
int ans=0,mn=INT_MIN;
// 贪心
for(auto x:v){
//当前数对的左边值大于mn,那可以加入,且相对于后面的数对是最优的,因为右边值是递增的。
if(mn<x.second){
ans++;
mn=x.first;
}
}
return ans;
}
};
方法三:贪心+二分,类似最长上升子序列解法。时间复杂度0(n)。
C++版本:
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
sort(pairs.begin(),pairs.end());
int n=pairs.size();
//维护最长上升子序列的右边值
vector<int> v(n+1);
//哨兵
v[0]=-2000;
//最长上升子序列长度
int top=1;
for(auto x:pairs){
int l=0,r=top;
// 二分找到符合当前数对的左边值 > 前面数对的右边值,的最后一个位置的右边
while(l<r){
int mid=(l+r)/2;
if(v[mid]<x[0]) l=mid+1;
else r=mid;
}
//子序列长度增加
if(l==top){
v[l]=x[1];
top++;
}
//维护子序列长度为l+1时的“最小的右边值”
v[l]=min(v[l],x[1]);
}
return top-1;
}
};
也可以用自带的二分
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
sort(pairs.begin(),pairs.end());
vector<int> v;
v.push_back(INT_MIN);
for(int i=0;i<pairs.size();i++){
int id=lower_bound(v.begin(),v.end(),pairs[i][0])-v.begin();
if(id==v.size()) v.push_back(pairs[i][1]);
else v[id]=min(v[id],pairs[i][1]);
}
return v.size()-1;
}
};