力扣 1218最长定差子序列 (java题解 动态规划)

在这里插入图片描述
在这里插入图片描述

emmm,刚开始做这个题,我没有想到动态规划,我只想到了暴力求解,遍历,找最长,但是知道测试样例的范围之后,我就知道这不行,会爆。所以我就识相的去翻了题解。

思路

    当遍历到一个数字num时,判断num-difference在不在dp数组里就知道能不能形成以num为结尾的等差数组,记录这个等差数组的长度,遍历后面的数的时候就能用到。
    用例三来举例:arr = [1,5,7,8,5,3,4,2,1], difference = -2,辅佐数组为dp[],
1.当遍历到1的时候,发现1-(-2)=3不在dp数组中,记录dp[1]=1,表示以1结尾的等差数列只有1个数
2.当遍历到5的时候,发现5-(-2)=7不在dp数组中,记录dp[5]=1
3.当遍历到7的时候,发现7-(-2)=9不在dp数组中,记录dp[7]=1
4.当遍历到8的时候,发现8-(-2)=10不在dp数组中,记录dp[10]=1
5.当遍历5的时候,发现5-(-2)=7在dp数组中,且dp[7]=1,所以dp[5]=dp[7]+1=2,表示以5结尾的等差数列的长度为2
6.当遍历到3的时候,发现3-(-2)=5在dp数组中,且dp[5]=2,所以dp[3]=dp[5]+1=3,表示以3结尾的等差数列的长度为3
7.当遍历到4的时候,发现4-(-2)=6不在dp数组中,记录dp[4]=1
8.当遍历到2的时候,发现2-(-2)=4不在dp数组中,记录dp[2]=1
9.当遍历到1的时候,发现1-(-2)=3在dp数组中,所以dp[1]=d[3]+1=4,表示以1为结尾的等差数列的长度为4。
然后在dp数组中最大的就是4,所以最长的等差子序列就是4.

所以我们能推出来,dp[num]=dp[num-different]+1

class Solution {
    public int longestSubsequence(int[] arr, int difference) {
        int ans = 0;
        int[] dp = new int[40001];
        for (int num : arr) {
            dp[num + 20000] = dp[num + 20000 - difference] + 1;
            ans = Math.max(ans, dp[num + 20000]);
        }
        return ans;
    }
}

    然后我们据需要来说说dp数组的范围,dp[i]表示以i为末尾的等差数列的长度,然后题目中又说-10^4<= arr[i]<= 10^4,但是由于arr[i]存在负数,而arr[i]是要做dp数组的数组下标的,所以在往dp数组里存的时候,就需要+20000保证数组下标不为负数,为什么是+20000?因为arr[i]的最小值是-10000,difference的最大值是10000,所以他们两个的差最小为-20000,表示数组下标需要到-20000去,所以需要再加上20000,保证数组下标为正。所以dp数组本来应该是定义为10000-(-10000)=2000的,然后加上给下标加的2000,数组长度要大于40000,所以40001正好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值