其他分享
首页 > 其他分享> > 1027. 最长等差数列

1027. 最长等差数列

作者:互联网

难度 medium
给定一个整数数组 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

解题思路:这道题目我用了接近一个小时还是没有解决,好菜,用来一个很笨的方法,结果超时了,然后参考了题解写出来的,这道题目用的是动态规划,动态规划还是容易跪,一定要把这东西记下来,不然这个情况到了秋招该怎么办。说回正题,这道题用的是等差数列,等差数列有一个重要的性质就是对于一个等差数列[nums[i], nums[j], nums[k]],有nums[j]2 = nums[i]+nums[k],因此我们就是利用了这个性质。用一个二维数组dp[i][j]表示以下标i,j对应的两个数字为结尾的等差数列,那么如果它存在前一个数,那前一个数就是nums[i]2-nums[j],于是我们用一个哈希map来保存数值和下标的对应关系,如果map中存在这个值,就更新动态规划方程,即dp[i][j] = dp[map.get(nums[i]*2-nums[j])][i]+1,否则说明这前一个数不存在,也就是以dp[i][j]结尾的等差数列最长就是nums[i]和nums[j]组成的数组,其长度为2,于是将dp[i][j]赋为2即可。我们还需要一个res来记录dp[i][j]的最大值,动态更新最后返回即可。

代码 t90 s70 java

class Solution {
    public int longestArithSeqLength(int[] nums) {
        HashMap<Integer,Integer> map = new HashMap<>();
        int n = nums.length, res = Integer.MIN_VALUE;
        int[][] dp = new int[n][n];
        for(int i=0; i<n-1; i++){
            for(int j=i+1; j<n; j++){
                int t = nums[i] * 2 - nums[j];
                if(map.containsKey(t)) dp[i][j] = dp[map.get(t)][i] + 1;
                else dp[i][j] = 2;
                res = Math.max(res, dp[i][j]);
            }
            map.put(nums[i], i);
        }
        return res;
    }
}

参考资料
https://leetcode-cn.com/problems/longest-arithmetic-subsequence/solution/dong-tai-gui-hua-ha-xi-biao-you-hua-by-acw_wangdh1/

标签:10,1027,nums,int,map,等差数列,最长,dp
来源: https://www.cnblogs.com/zhengxch/p/14902134.html