LeetCode 873 Length of Longest Fibonacci Subsequence (hash 或 dp)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tc_To_Top/article/details/89889651

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.

(Recall that a subsequence is derived from another sequence A by deleting any number of elements (including none) from A, without changing the order of the remaining elements.  For example, [3, 5, 8]is a subsequence of [3, 4, 5, 6, 7, 8].)

Example 1:

Input: [1,2,3,4,5,6,7,8]
Output: 5
Explanation:
The longest subsequence that is fibonacci-like: [1,2,3,5,8].

Example 2:

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].

Note:

  • 3 <= A.length <= 1000
  • 1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9
  • (The time limit has been reduced by 50% for submissions in Java, C, and C++.)

题目链接:https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/

题目分析:先无脑模拟fib数组的运算

61ms,时间击败75.8%

class Solution {
    public int lenLongestFibSubseq(int[] A) {
        int n = A.length;
        HashSet<Integer> set = new HashSet<>();
        for (int i = 0; i < A.length; i++) {
            set.add(A[i]);
        }
        int ans = 0, cur = 0, a = 0, b = 0, c = 0;
        for (int i = 0; i < A.length; i++) {
            for (int j = i + 1; j < A.length; j++) {
                a = A[i];
                b = A[j];
                c = a + b;
                cur = 0;
                while (set.contains(c)) {
                    cur++;          
                    a = b;
                    b = c;
                    c = a + b;
                }
                ans = Math.max(ans, cur == 0 ? 0 : cur + 2);
            }
        }
        return ans;
    }
}

考虑加些优化

48ms,时间击败88.11%

class Solution {
    public int lenLongestFibSubseq(int[] A) {
        HashSet<Integer> set = new HashSet<>();
        int ma = 0;
        for (int i = 0; i < A.length; i++) {
            set.add(A[i]);
            if (A[i] > ma) {
                ma = A[i];
            }
        }
        int ans = 0, cur = 0, a = 0, b = 0, c = 0;
        for (int i = 0; i < A.length; i++) {
            if (ans >= A.length - i - 3) {
                break;
            }
            for (int j = i + 1; j < A.length; j++) {
                c = A[i] + A[j];
                if (c > ma) {
                    break;
                }
                if (set.contains(c)) {
                    a = A[i];
                    b = A[j];
                    cur = 2;
                    while (set.contains(c)) {
                        cur++;
                        a = b;
                        b = c;
                        c = a + b;
                    }
                    if (cur > ans) {
                        ans = cur;
                    }   
                }
            }
        }
        return ans;
    }
}

考虑dp,dp[i][j]表示最后两个点为i和j时的最长序列长度,序列单调增,故可以使用两点法

21ms,时间击败98.48%

class Solution {
    public int lenLongestFibSubseq(int[] A) {
        int n = A.length, ans = 0, sum = 0;
        int[][] dp = new int[n][n];
        for (int i = 1; i < n; i++) {
            int l = 0, r = i - 1;
            while (l < r) {
                sum = A[l] + A[r];
                if (sum < A[i]) {
                    l++;
                } else if (sum > A[i]) {
                    r--;
                } else {
                    dp[r][i] = dp[l][r] + 1;
                    if (dp[r][i] > ans) {
                        ans = dp[r][i];
                    }
                    l++;
                    r--;
                }
            }
        }
        
        return ans == 0 ? 0 : ans + 2;
    }
}

 

 

展开阅读全文

没有更多推荐了,返回首页