题目来源:https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/
大致题意:
给定一个数组和一个差值 diff,找最长的相邻元素差都为 diff 的子序列的长度
思路
我寻思这就是 LIS 的微改版本,于是按着 LIS 动态规划的方法走了一遍,结果超时了
题解就是 LIS dp的优化版本
动态规划
在之前的思路中,使用 dp[i] 存下当前位置 i 的最长上升子序列长度,于是在本题,可以使用 dp[i] 存下当前位置 i 的最长定差子序列长度,更新方法为
- dp[i] = max(dp[i], dp[j] + 1),当 nums[i] - nums[j] = diff 时、
于是可以看到,更新时只会找在此位置之间的值为 nums[i] - d 的元素所在位置的最长定差子序列长度,只和该元素有关,而之前的位置中若没有该元素,那么显然 dp[i] 为 1
因而,可以用 dp[v] 表示当前以值为 v 结尾的最长定差子序列长度,更新方法为
- dp[v] = dp[v - diff] + 1,若 dp[v - diff] 不存在,则为 0
我们可以使用哈希表存下值和长度的键值对
代码:
public int longestSubsequence(int[] arr, int difference) {
// 用哈希表存下值和长度的键值对
Map<Integer, Integer> map = new HashMap<>();
int ans = 0;
for (int num : arr) {
// 更新 dp[v] = dp[v - diff] + 1,若 dp[v - diff] 不存在,则为 0
map.put(num, map.getOrDefault(num - difference, 0) + 1);
// 更新最大长度
ans = Math.max(map.get(num), ans);
}
return ans;
}