题目描述
给定一个整数数组 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 是等差的。
示例 1:
输入:[3,6,9,12]
输出:4
解释:
整个数组是公差为 3 的等差数列。
示例 2:
输入:[9,4,7,2,10]
输出:3
解释:
最长的等差子序列是 [4,7,10]。
示例 3:
输入:[20,1,15,3,10,5,8]
输出:4
解释:
最长的等差子序列是 [20,15,10,5]。
提示:
2 <= A.length <= 2000 0 <= A[i] <= 10000
思路分析
在该题中单个状态为:第i个数差为diff时的最长序列的值。
状态转移方程为:
第i个数,差为diff时的最长序列值 = max(A, B)
A: 与数i一起构成差为diff的数j,且当数j差为diff的最长序列值+1
B: 第i个数,差为diff时的最长序列值 // 因为与i构成差值diff的不止j也有可能是k等等
AC代码
var longestArithSeqLength = function(A) {
let maxLen = 0
let dp = [{}]
let size = A.length
for(let i = 1; i < size; i++) {
!dp[i] && ( dp[i] = {} )
for(let j = 0; j < i; j++) {
let diff = A[i] - A[j]
!dp[i][diff] && ( dp[i][diff] = 2 )
if(dp[j][diff] > 0) {
dp[i][diff] = Math.max(dp[j][diff] + 1, dp[i][diff])
}
maxLen = Math.max(dp[i][diff], maxLen)
}
}
return maxLen
};
总结
动态规划使用条件:
1.题目有个阈值(最大、小、长、短...之类的)
2.前一个最X状态可以构成后一个最X状态