LeetCode - 873. Length of Longest Fibonacci Subsequence

A sequence X_1, X_2, ..., X_n is fibonacci-like if:

  • n >= 3
  • X_i + X_{i+1} = X_{i+2} for all i + 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。

猜你喜欢

转载自blog.csdn.net/Bob__yuan/article/details/81230075
今日推荐