题目描述
给你一个整数数组 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]。
#include <iostream>
#include <unordered_map>
#include <vector>
#include <fstream>
using namespace std;
class Solution {
public:
int longestSubsequence(vector<int>& arr, int difference) {
int ans = 0;
int n = arr.size();
unordered_map<int,int>m;
vector<vector<int>>dp(n,vector<int>(2,0)); //dp[i][0]表示数组区间[0,i]第i个数不被选的情况下可以获得的最大子序列的长度值
dp[0][1] = 1; //dp[i][1]表示数组区间[0,i]第i个数被选的情况下可以获得的最大子序列的长度值
m[arr[0]] = 0;
for(int i = 1;i < arr.size();i++){
dp[i][0] = max(dp[i - 1][1],dp[i - 1][0]);
if(m.count(arr[i] - difference)){ //如果上一个等差序列中的值存在于数组[0,i)中,则dp[i][1]的值为上一个序列数j的值+1 即:dp[j][1] + 1;
dp[i][1] = dp[m[arr[i] - difference]][1] + 1;
}
else dp[i][1] = 1;
m[arr[i]] = i; //map 存放数组[0,i]的数值为键,它们的数组下标为键值
}
return max(dp[n - 1][0],dp[n - 1][1]);
}
};
动态规划代码优化:
class Solution {
public:
int longestSubsequence(vector<int>& arr, int difference) {
int ans = 0;
unordered_map<int,int>dp; //dp[i] 表示以 arr[i] 为结尾的最长的等差子序列的长度
for(auto v : arr){
dp[v] = dp[v - difference] + 1;
ans = max(ans,dp[v]);
}
return ans;
}
};
main函数:
int main(){
Solution solve;
const char *file = "source.txt"; //存放用例 第一行存放数组 第二行存放diffrent值
vector<int>arr;
int diff = 0;
ifstream fin;
fin.open(file);
if(fin.is_open()){
char ch;
int item = 0;
int row = 0;
int minus = 1;
while(fin.get(ch)){ //每次从文件中提取一个字符
if(row % 2 == 0){ //如果是第0,2,4,6,8等偶数行 为arr数组
if(ch == '[')continue;
else if(ch == '-'){
minus = -1;
}
else if(isdigit(ch)){
item *= 10;
item += (ch - '0');
}
else if(ch == ',' || ch == ']'){ //如果遇到‘,’或是‘]’ 则将数字存入中
if(minus == -1)arr.push_back(-item);
else arr.push_back(item);
item = 0;
minus = 1;
}
else if(ch == '\n'){
row++;
}
}
else{ //如果是1,3,5 奇数行 为diffrent数值
if(isdigit(ch)){
diff *= 10;
diff += (ch -'0');
}
else if(ch == '-'){
minus = -1;
}
else if(ch == '\n'){
row++;
if(row != 10){
cout<<"arr = [";
for(int i = 0;i < arr.size();i++){
cout<<arr[i];
if(i != arr.size()-1)cout<<",";
}
cout<<"]"<<endl;
}
if(minus == 1){
cout<<" diffrent = "<<diff<<endl;
}
else cout<<" diffrent = "<<-diff<<endl;
diff = minus * diff;
int ans = solve.longestSubsequence(arr,diff);
cout<<"ans = "<<ans<<endl;
diff = 0;
arr.clear();
item = 0;
minus = 1;
}
}
}
cout<<"arr = [";
for(int i = 0;i < arr.size();i++){ //到达文件末尾
cout<<arr[i];
if(i != arr.size()-1)cout<<",";
}
cout<<"]"<<endl;
if(minus == 1){
cout<<" diffrent = "<<diff<<endl;
}
else cout<<" diffrent = "<<-diff<<endl;
diff = minus * diff;
int ans = solve.longestSubsequence(arr,diff);
cout<<"ans = "<<ans<<endl;
}
fin.clear();
fin.close();
return 0;
}
用例文件: