斐波那契数列由前两项决定,所以我们遍历前两项的所有可能,然后去题目给的数字里验证最长的数列是多少。前两项总共的组合有O(N ^ 2)个,对于斐波那契数列,f(n) > 2 * f(n - 2)是必定成立的,数列每隔两项就至少会翻一倍。所以最长的序列也就2 * log M,M为数组的最大值。时间复杂度O(N^2 * log M),空间复杂度O(n),用hash set存,代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int lenLongestFibSubseq(vector<int>& A) { | |
int len = A.size(), res = 0; | |
unordered_set<int> set; | |
for (const auto& num : A) | |
set.insert(num); | |
for (int i = 0; i < len; ++i) | |
for (int j = i + 1; j < len; ++j) | |
res = max(res, FibLen(set, A[i], A[j])); | |
return res; | |
} | |
private: | |
int FibLen(unordered_set<int>& set, int f1, int f2) | |
{ | |
int len = 2; | |
while (true) | |
{ | |
int f3 = f1 + f2; | |
if (set.find(f3) == set.end())break; | |
++len; | |
f1 = f2; | |
f2 = f3; | |
} | |
return len >= 3 ? len : 0; | |
} | |
}; |
既然数列可以由前两项决定,那当然也可以由后两项决定,那么我们就可以参考LIS的的思路。DP[i][j]代表以A[i], A[j]两项结尾的数列,对于每个j,我们遍历之前的所有i,如果输入数组中存在k = A[i] - A[j] && k < A[j],我们更新dp[A[i]][A[j]] = max(dp[A[i]][A[j]], dp[k][A[i]] + 1)。时间复杂度O(n ^ 2),空间复杂度O(n^2),代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int lenLongestFibSubseq(vector<int>& A) { | |
int len = A.size(), res = 0; | |
unordered_map<int, int> map; | |
for (int i = 0; i < len; ++i)map[A[i]] = i; | |
//longest fib len for seq ends at ..., A[i], A[j] | |
//compress i j to i * len + j, otherwise TLE | |
unordered_map<int, int> dp; | |
for (int i = 0; i < len; ++i) | |
{ | |
for (int j = 0; j < i; ++j) | |
{ | |
//don't set dp[key] = 2 before this line, otherwise we will have MLE | |
if (A[i] - A[j] >= A[j] || map.find(A[i] - A[j]) == map.end())continue; | |
int key = j * len + i; | |
int k = map[A[i] - A[j]]; | |
dp[key] = max(dp[key], 1 + (dp[k * len + j]? dp[k * len + j]: 2));//set here to save space | |
res = max(res, dp[key]); | |
} | |
} | |
return res >= 3 ? res : 0; | |
} | |
}; |
No comments:
Post a Comment