给你一个整数数组 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,所以范围为0到20000
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;
}
}