题目:
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.
A subsequence is a sequence that can be derived from arr by deleting some or no elements without changing the order of the remaining elements.
给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr 中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。
子序列是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除任何元素而从 arr 派生出来的序列。
思路:
首先想到的是利用和“最长上升子序列”差不多的动态规划方法, 从头到尾每个数扫描一次,dp[i]代表扫描到第i个数字时, 以该数字为结尾的最长等差子序列的长度, 但是对于每个数字, 都要重新扫描一遍前面的每一个数字, 寻找合适的(符合该数字减公差)且最大的(满足最长这一条件), 因此复杂度为O(n^2).
优化思路为, 利用"知道公差则确定上一个数字"这一原理进行优化, 可以利用哈希表一一对应的特性降低复杂度. dp[i]代表以数字i结尾的最长等差数列的长度. 复杂度为O(n)
哈希表初始化之后, 某个映射的结果默认为0?
题解:
普通算法
class Solution {
public:
int longestSubsequence(vector<int> &arr, int difference) {
int answer = 0;
int dp[10000000]={0};
for (int i=0;i<arr.size();++i) {
for(int j=0;j<i;++j){
if((arr[j]+difference)==arr[i]) dp[i]=dp[j]+1;
}
}
return *max_element(dp,dp+arr.size())+1;
}
};
优化算法
class Solution {
public:
int longestSubsequence(vector<int> &arr, int difference) {
int answer = 0;
unordered_map<int, int> dp; //<number, the longest length of this number's..>
for (int v: arr) {
dp[v] = dp[v - difference] + 1;
answer = max(answer, dp[v]);
}
return answer;
}
};