给定一个整数数组 A,返回 A 中最长等差子序列的长度。
回想一下,A 的子序列是列表 A[i_1], A[i_2], …, A[i_k] 其中 0 <= i_1 < i_2 < … <
i_k <= A.length - 1。并且如果 B[i+1] - B[i]( 0 <= i < B.length - 1)
的值都相同,那么序列 B 是等差的。
这道题主要的方法是采用数据结构将遍历过的部分的子序列的结果保存下来,以下标-公差-长度为保存结构,第一想到的是Map的数据结构,但是结果虽然正确时间复杂度却意外的非常高,将map改为数据结构之后,时间复杂度下降了很多。
//Map数据结构进行保存
public static int longestArithSeqLength(int[] A) {
Map<Integer,Integer>[] maps=new Map[A.length];
int maxLen=0;
for(int i=0;i<A.length;i++){
Map<Integer,Integer> mapi=new HashMap<>();
for(int j=i-1;j>=0;j--){
Map<Integer,Integer> record=maps[j];
int len=0;
if(!mapi.containsKey(A[i]-A[j])){
if(record!=null&&record.containsKey(A[i]-A[j])){
mapi.put(A[i]-A[j],len=record.get(A[i]-A[j])+1);
}else{
mapi.put(A[i]-A[j],len=2);
}
}
maxLen=Math.max(maxLen,len);
}
maps[i]=mapi;
}
System.out.println(maxLen);
return maxLen;
}
//改为数组进行保存,因为公差可能为负数,这里要将公差加10000
public static int longestArithSeqLength2(int[] A) {
Map<Integer,Integer>[] maps=new Map[A.length];
int[][]dp=new int[A.length][20001];
int maxLen=0;
for(int i=0;i<A.length;i++){
for(int j=i-1;j>=0;j--){
int len=0;
if(dp[i][A[i]-A[j]+10000]==0){
if(dp[j][A[i]-A[j]+10000]!=0){
len=dp[j][A[i]-A[j]+10000]+1;
}else{
len=2;
}
dp[i][A[i]-A[j]+10000]=len;
}
maxLen=Math.max(maxLen,len);
}
}
System.out.println(maxLen);
return maxLen;
}
从提交结果上看,其实就是空间复杂度提高了,降低时间复杂度