题目链接

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;    }};