题目链接:https://leetcode.cn/problems/longest-arithmetic-subsequence-of-given-difference/
一.题目介绍
二.题目分析
这道题如果我们用常规思路来解决,方法与"最长递增子序列"的解法一致,无非就是把判断条件改为 if(arr[i] - diff == arr[j]),但是这个题目的数据量为:
所以用O(n方)的时间复杂度解决最后就会导致超出时间限制,所以我们必须换一个思路。
在"最长递增子序列"一题中,我们在确定dp[i]位置然后向前找合适的dp[j]位置时,对于 j 的位置和对应数值我们都是不知道的,所以才要遍历0 ~ j区间的所有数,但是此题中我们可以得知:若arr[i] - diff == arr[j],则i,j这两个数是可以构成等差子序列的,说明这期间我们知道 j 位置对应的数值但是还是不知道位置,所以我们设计hash表存放数据,以空间换时间省略遍历。
undered_map<int, int>分别存放arr[i]的数值,最长定差子序列的长度。所以我们直接在hash表中做动态规划,大大减少了时间的消耗。
三.状态分析 ![](https://i-blog.csdnimg.cn/blog_migrate/cac3a0d8068bc4d3dd005d47aa31a8a5.png)
这里注意在循环hash[arr[i]] = hash[arr[i] - diff] 的过程中也是hash表填表的过程,没出现过的元素都会在hash中更新,然后默认的出现次数为0。
四.完整代码
int longestSubsequence(vector<int>& arr, int diff)
{
// 1.创建hash表
// 2.处理边界条件
// 3.填写hash表
// 4.返回hash表中记录dp[i]最大的一个
int n = arr.size(), res = 1;
unordered_map<int, int> hash; //<arr[i], dp[i]>
hash[arr[0]] = 1;
for(int i = 1; i < n; i++)
{
hash[arr[i]] = hash[arr[i] - diff] + 1;
res = max(res, hash[arr[i]]);
}
return res;
}