1.题目描述
给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr 中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。
子序列 是指在不改变其余元素顺序(划重点)的情况下,通过删除一些元素或不删除任何元素而从 arr 派生出来的序列。
2.解题思路
- 解题方法:动态规划
动态规划按题中的意思是,从头到尾遍历数组。依次保存以当前数字为首的,最长子序列,并且这个子序列不改变其余元素顺序(该说明对本题很重要,后面会讲),后面的数字如果在减去“等差(difference)”后能找到对应的子序列,则直接调用之前的子序列,再在结果上加1,并且保存。
举个例子,有数组
首先需要依次遍历数组。
第1次遍历(dp指保存子序列的容器):
第2次遍历:
第3次遍历:
第4次遍历:
第5次遍历:
第6次遍历:
第7次遍历:
第8次遍历:
第9次遍历:
遍历完后,找出dp中最大值即可。
- 重点理解——不改变其余元素顺序
如果我们把上面的例子修改一下,删除数组末尾的1:
那么按照,本题动态规划的思路解题,得出的答案是3。为什么结果是3呢?因为题目中给出了子序列的定义——“不改变其余元素顺序”,所以得出的最长序列应该是[7,5,3],后面没有了1。
3.代码
class Solution {
public:
int longestSubsequence(vector<int> &arr, int difference) {
int ans = 0;
unordered_map<int, int> dp;
for (int v: arr) {
dp[v] = dp[v - difference] + 1;
ans = max(ans, dp[v]);
}
return ans;
}
};