LeetCode/最长斐波那契子序列的长度
作者:互联网
给定一个严格递增的正整数数组形成序列 arr ,找到 arr 中最长的斐波那契式的子序列的长度。如果一个不存在,返回0
1. 暴力法
先用哈希表记录,再二重循环遍历转移,会存在重复遍历
class Solution {
public:
int lenLongestFibSubseq(vector<int>& arr) {
unordered_set<int> s(arr.begin(),arr.end());
int max_ = 0;
for(int i=0;i<arr.size()-2;i++){
for(int j=i+1;j<arr.size()-1;j++){
int first = arr[i];
int second = arr[j];
if(!s.count(first+second)) continue;//不存在跳过
int count = 2;
while(s.count(first+second)){
count++;
second = second +first;//转移到下一状态,继续往后寻找
first = second - first;
}
max_ =max(max_,count);
}
}
return max_;
}
};
2. 动态规划
dp[i][j]表示以i,j结尾的子序列最大长度
class Solution {
public:
int lenLongestFibSubseq(vector<int>& A) {
int n = A.size();
unordered_map<int, int> intMap;
for (int i = 0; i < n; i++)
intMap[A[i]] = i; //记录值对应索引
vector<vector<int>> dp(n, vector<int>(n, 2));//dp[i][j]表示以i、j结尾最大长度
int MAX = 0;
for (int i = 0; i < n; i++) //二重循环从前往后遍历遍历
for (int j = i + 1; j < n; j++) {
int diff = A[j] - A[i];
if (intMap.count(diff)&&intMap[diff] < i) {
dp[i][j] = max(dp[i][j], dp[intMap[diff]][i] + 1);
MAX = max(MAX, dp[i][j]);
}
}
return MAX > 2? MAX : 0;
}
};
另一种形式的动态规划
class Solution {
public:
int lenLongestFibSubseq(vector<int>& arr) {
unordered_map<int, int> indices;
int n = arr.size();
for (int i = 0; i < n; i++)
indices[arr[i]] = i;
vector<vector<int>> dp(n, vector<int>(n,2));
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = i - 1; j >= 0 && arr[j] * 2 > arr[i]; j--) {
if (indices.count(arr[i] - arr[j])){
int k = indices[arr[i] - arr[j]];
dp[j][i] = max(dp[j][i],dp[k][j] + 1);
}
ans = max(ans, dp[j][i]);
}
}
return ans==2?0:ans;
}
};
标签:契子,arr,int,斐波,vector,ans,intMap,LeetCode,dp 来源: https://www.cnblogs.com/929code/p/16460049.html