LeetCode 1218 最长定差子序列
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/
博主Github:https://github.com/GDUT-Rp/LeetCode
题目:
给你一个整数数组 arr
和一个整数 difference
,请你找出并返回 arr
中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference
。
子序列 是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除任何元素而从 arr 派生出来的序列。
示例 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
<
=
a
r
r
.
l
e
n
g
t
h
<
=
1
0
5
1 <= arr.length <= 10^5
1<=arr.length<=105
−
1
0
4
<
=
a
r
r
[
i
]
,
d
i
f
f
e
r
e
n
c
e
<
=
1
0
4
-10^4 <= arr[i], difference <= 10^4
−104<=arr[i],difference<=104
解题思路:
方法一:动态规划
对于列表中的每个数据,后一个数与前一个等差的数字有关,这里可以联想到动态规划。
因此我们可以有序的进行遍历,以一个map的形式保存当前值最长的等差序列长度[num] = count,即[1, 2],difference=1,我们遍历到1,map[1-1]不存在,则为1,map[1]=1,遍历到2,map[2-1]存在,则map[2] = map[1] + 1,同理可得 dp[v] = dp[v-difference] + 1。
C++
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;
}
};
Golang
func longestSubsequence(arr []int, difference int) (ans int) {
dp := map[int]int{}
for _, v := range arr {
dp[v] = dp[v-difference] + 1
if dp[v] > ans {
ans = dp[v]
}
}
return
}
Python
class Solution:
def longestSubsequence(self, arr: List[int], difference: int) -> int:
dp = {}
ans = 1
for v in arr:
if v - difference not in dp:
dp[v] = 1
continue
dp[v] = dp[v - difference] + 1
ans = max(ans, dp[v])
return ans
复杂度分析
时间复杂度: O ( n ) O(n) O(n)。
空间复杂度: O ( n ) O(n) O(n)。