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
. If one does not exist, return 0.
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。