一.问题描述
Given an integer array arr
and an integer difference
, return the length of the longest subsequence in arr
which is an arithmetic sequence such that the difference between adjacent elements in the subsequence equals difference
.
Example 1:
Input: arr = [1,2,3,4], difference = 1
Output: 4
Explanation: The longest arithmetic subsequence is [1,2,3,4].
Example 2:
Input: arr = [1,3,5,7], difference = 1
Output: 1
Explanation: The longest arithmetic subsequence is any single element.
Example 3:
Input: arr = [1,5,7,8,5,3,4,2,1], difference = -2
Output: 4
Explanation: The longest arithmetic subsequence is [7,5,3,1].
Constraints:
1 <= arr.length <= 10^5
-10^4 <= arr[i], difference <= 10^4
二.解决思路
动态规划题目,重点在于如何更新下一个状态
dp[i] 表示在arr[0:i-1]中以arr[i]结尾的子序列的最大长度
考虑dp[i+1],
dp[i+1]=dp[num2pos[arr[i+1]-difference]]+1 if arr[i+1]-difference in arr[0:i]
如果之前有相差difference的元素,那就把以它结尾的最大子序列长度+1就好了
num2pos是一个字典,用于映射元素的值与元素坐标
映射元素坐标的时候,从arr[0]~arr[i]可能有重复元素,不过没关系,我们只需要映射相同元素最后一个元素的坐标就可以了
因为以相同元素结尾的子序列中,最后一个元素的子序列是最长的。
更新:
发现一个超简介的算法
其实我们并不需要真正知道每个num的position
我们关注的是以arr[i]-difference结尾的子序列的最长
所以直接记录以arr[i]-difference结尾的子序列的最长就好了
源码给在下面
更多leetcode算法题解法请关注我的专栏leetcode算法从零到结束或关注我
欢迎大家一起套路一起刷题一起ac
三.源码
class Solution:
def longestSubsequence(self, arr: List[int], diff: int) -> int:
res = {}
for num in arr:
res[num] = res.get(num-diff,0)+1
return max(res.values())