LeetCode - 873. Length of Longest Fibonacci Subsequence
阿新 • • 發佈:2018-11-29
A sequence X_1, X_2, ..., X_n
is fibonacci-like if:
n >= 3
X_i + X_{i+1} = X_{i+2}
for alli + 2 <= n
Given a strictly increasing array A
of positive integers forming a sequence, find the length of the longest fibonacci-like subsequence of A
Examples:
Input: [1,2,3,4,5,6,7,8]
Output: 5
Explanation: The longest subsequence that is fibonacci-like: [1,2,3,5,8].
Input: [1,3,7,11,12,14,18] Output: 3 Explanation: The longest subsequence that is fibonacci-like: [1,11,12], [3,11,14] or [7,11,18].
思路:
這題就是說找一串能滿足 x[i] + x[i + 1] = x[i + 2] 的數,最關鍵的是,這些數在原來的序列中,不需要是挨著的,只需要保持原來的順序不變就行。我的思路就是一個一個找,每次更新最長的長度。O(n^2)的時間來遍歷兩遍整個序列,每次從 A[i] 和 A[i + 1] 開始,找能夠湊成斐波那契數列的最長的長度。AC程式碼如下:
int lenLongestFibSubseq(vector<int>& A) { unordered_set<int> set_A(A.begin(), A.end()); int len = A.size(); int max_len = 0; for(int i = 0; i < len; i++) { for(int j = i + 1; j < len; j++) { int a = A[i], b = A[j]; int tmp_len = 2; while(set_A.find(a + b) != set_A.end()) { b = a + b; a = b - a; // 讓 a 等於原來的 b ,如果先a = b,b 就不好設了 tmp_len += 1; max_len = max(max_len, tmp_len); } } } return max_len; }
這樣的速度不快,擊敗 43.02% 的程式碼。看到 LeetCode Discuss 裡最多 view 的程式碼是下邊這種:
int lenLongestFibSubseq(vector<int>& A)
{
unordered_set<int> s(A.begin(), A.end());
int res = 0;
for (int i = 0; i < A.size(); ++i) {
for (int j = i + 1; j < A.size(); ++j) {
int a = A[i], b = A[j], l = 2;
while (s.count(a + b))
b = a + b, a = b - a, l++;
res = max(res, l);
}
}
return res > 2 ? res : 0;
}
這樣的擊敗 51.37% 的程式碼,這樣看來,在整個序列裡,基本還是能夠找到至少三個長度的斐波那契數列的(也就是基本有了a和b,一定能找到 a + b),這樣的話明顯下邊這種快,但是這樣也用了184ms,這種的時間複雜度是 O(N^2 *logN),如果用動態規劃,可以做到70ms。