题目链接
Leetcode.1027 最长等差数列 Rating : 1759
题目描述
给你一个整数数组 nums
,返回 nums
中最长等差子序列的长度。
回想一下,nums
的子序列是一个列表 nums[i1], nums[i2], ..., nums[ik]
,且 0 <= i1 < i2 < ... < ik <= nums.length - 1
。并且如果 seq[i+1] - seq[i]( 0 <= i < seq.length - 1)
的值都相同,那么序列 seq
是等差的。
示例 1:
输入:nums = [3,6,9,12]
输出:4
解释:
整个数组是公差为 3 的等差数列。
示例 2:
输入:nums = [9,4,7,2,10]
输出:3
解释:
最长的等差子序列是 [4,7,10]。
示例 3:
输入:nums = [20,1,15,3,10,5,8]
输出:4
解释:
最长的等差子序列是 [20,15,10,5]。
提示:
- 2 < = n u m s . l e n g t h < = 1000 2 <= nums.length <= 1000 2<=nums.length<=1000
- 0 < = n u m s [ i ] < = 500 0 <= nums[i] <= 500 0<=nums[i]<=500
解法:动态规划
我们定义
f
(
i
,
d
)
f(i,d)
f(i,d) 为选择以 nums[i]
结尾的,公差为 d
的,最大段数。(比如:1 , 2 , 3
,就是 两段)
用 ans
记录遍历过程中的最大值,最后返回 ans + 1
。因为段数 + 1 才是长度。
时间复杂度: O ( n 2 ) O(n^2) O(n2)
C++代码:
class Solution {
public:
int longestArithSeqLength(vector<int>& nums) {
int n = nums.size();
int f[n][1001];
memset(f,0,sizeof f);
int ans = 0;
for(int i = 0;i < n;i++){
for(int j = 0;j < i;j++){
int d = nums[i] - nums[j] + 500;
f[i][d] = f[j][d] + 1;
ans = max(f[i][d] , ans);
}
}
return ans + 1;
}
};