1. 程式人生 > >LeetCode - 873. Length of Longest Fibonacci Subsequence

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。