力扣题解(最长等差数列)

1027. 最长等差数列

给你一个整数数组 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 是等差的。

思路:

本题和求斐波那契数列做法很相似,不同点也就是判断不同,因此同样采用多维dp来求解。规定dp[i][j]是i位置元素在前,j位置元素在后构成等差子序列的最大长度。此时在(0-i-1)之间找k,使得nums[j]-nums[i]=nums[i]-nums[k],则nums[k]=2*nums[i]-nums[j],求符合条件的k,然后dp[i][j]=dp[k][i]+1。注意,此处也要求k位置一定小于i位置,否则k在i,j之间无法保证能在拥有i位置获得的最长等差数列加上k,j位置元素仍能构成等差数列。此外,在每次i指针往后移动时,将前一个位置元素保存到哈希表中,方便快速查找符合要求的元素。但不能在开始直接将一整个数组元素全部放入哈希表中,因为同一个元素出现在i之前和j之后可能会对结构产生影响,因为哈希表默认存放的是该元素最后一次出现的下标,这样会导致错误。而斐波那契数列那个题开始时全放入不会有影响,因为那个题是严格单调的,不会出现同一个元素在不同 下标。

class Solution {
public:
    int longestArithSeqLength(vector<int>& arr) {
         int n=arr.size();
     vector<vector<int>>dp(n,vector<int>(n,2));
     unordered_map<int,int>hash;
    hash[arr[0]]=0;
    int ss=0;

     for(int i=1;i<n;i++)
     { 
        for(int j=i+1;j<n;j++)
        {   
             int a=arr[i]*2-arr[j];
            if(hash.count(a)&&hash[a]<i)
            {
                 dp[i][j]=max(dp[i][j],dp[hash[a]][i]+1 );
            }
           
        }
        hash[arr[i]]=i;
     }
     int ret=0;
     for(auto e:dp)
     {  
        for(auto s:e)
        ret=max(ret,s);

     }

     return ret;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值