leetcode - 1218. 最长定差子序列 (使用哈希表)

给你一个整数数组 a r r arr arr 和一个整数 d i f f e r e n c e difference difference,请你找出 a r r arr arr 中所有相邻元素之间的差等于给定 d i f f e r e n c e difference difference 的等差子序列,并返回其中最长的等差子序列的长度。

示例 1:

输入:arr = [1,2,3,4], difference = 1
输出:4
解释:最长的等差子序列是 [1,2,3,4]。

示例 2:

输入:arr = [1,3,5,7], difference = 1
输出:1
解释:最长的等差子序列是任意单个元素。

示例 3:

输入:arr = [1,5,7,8,5,3,4,2,1], difference = -2
输出:4
解释:最长的等差子序列是 [7,5,3,1]。

提示:

1 <= arr.length <= 10^5
-10^4 <= arr[i], difference <= 10^4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
——————
解题思路一:使用哈希表,存储以数组中每个元素结尾的最长的等差子序列的长度,返回最大的值。

class Solution {
public:
    int longestSubsequence(vector<int>& arr, int difference) {
        unordered_map<int, int> index;  # 建立一个哈希表 
        int num = 1;  # 返回的最长等差子序列
        for(int i=0;i<arr.size();i++)
        {
            index[arr[i]] = index[arr[i]-difference] + 1;  # 状态转移方程
            num = max(index[arr[i]],num);  # 统计到当前为止的最长等差子序列
        }
        return num;
        
    }
};

解题思路二:不用哈希表,用数组存储状态变量。因为difference的值可能是负数,所以需要加一个偏置,具体原理和上面使用哈希表是一样的。

class Solution {
public:
    int longestSubsequence(vector<int>& arr, int difference) {
        int dp[20001]={0};  # 因为数组元素的取值范围为-10000+10000,加上偏置为10000,所以范围为020000
        int ans = 0;  # 用于存储最长等差子序列的长度
        for(int i = 0; i < arr.size(); ++i)
        {
            int x = arr[i]+10000;  # 给每个数加上一个偏置10000
            dp[x] = 1; # 这个赋值很重要,不能漏掉,因为后面判断x-difference的时候可能不会对dp[x]进行赋值,所以这里如果漏掉dp[x]=1,会导致bug的发生
            if(x - difference >= 0 && x - difference <= 20000)  # 因为x的范围是0-20000,如果x-difference的值不在0-20000之间,那么dp[x-difference]是不存在的,没有这个索引,所以可以忽略掉
                dp[x] = dp[x-difference] + 1;  # 如果x-difference在0-20000之间,就可以使用状态转移方程
            ans = max(ans, dp[x]);  # 统计ans的最大值
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值