开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
最长定差子序列
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/lo…
给你一个整数数组 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 <= arr.length <= 105 -104 <= arr[i], difference <= 104
解法
- 暴力循环:双重循环,在该元素之后进行一一比对
- python
class Solution:
def longestSubsequence(self, arr: List[int], difference: int) -> int:
n = len(arr)
max_length = 1
for i in range(n-1):
res = [i]
num = arr[i]
for j in range(i+1, n):
if arr[j] - num == difference:
res.append(j)
num = arr[j]
max_length = max(len(res), max_length)
return max_length
- c++
class Solution {
public:
int max(int x1, int x2)
{
return x1>x2?x1:x2;
}
public:
int longestSubsequence(vector<int>& arr, int difference) {
long length = arr.size();
int ans = 1;
int num;
for(long i=0; i<length-1;i++)
{
vector<int> res={};
num = arr[i];
res.push_back(i);
for(long j=i+1; j<length; j++)
{
if (arr[j]-num == difference)
{
res.push_back(j);
num = arr[j];
ans = max(ans, res.size());
}
}
}
return ans;
}
};
- 动态规划+哈希表: 状态转移方程
dp[v]=dp[v-difference]+1
。其中v是arr中的元素,这里哈希表使用的是defaultdict,转移关系是两个数的位置及关系符合等差要求时候,长度+1 - python
from collections import defaultdict
class Solution:
def longestSubsequence(self, arr: List[int], difference: int) -> int:
dp = defaultdict(int)
# max_lenth = 1
for v in arr:
dp[v] = dp[v-difference] + 1.
# max_lenth = max(max_lenth, dp[v])
# return max_lenth
return max(dp.values())
- c++
class Solution {
public:
int longestSubsequence(vector<int>& arr, int difference) {
int ans = 1;
unordered_map<int, int> dp;
for(int v: arr)
{
dp[v] = dp[v-difference] + 1;
ans = max(ans, dp[v]);
}
return ans;
}
};
复杂度分析
- 时间复杂度:
- 方法1:
- 方法2:时间复杂度:O(n)
- 空间复杂度:
- 方法1: O(n)
- 方法2:O(n)