873 Longest FIbonacci Subsequence


标签:dp,LCS

题目

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 Aby 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++.)

TLE LCS 思路

  1. 和1027 longest arithmetic sequence的思路一样,但是直接用的话,会TLE
  2. 注意数组是上升的序列,还在思考怎么解决

code

//
// Created by hanshan on 19-6-13.
//

#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
//[2,1,3,4,5,6,7,8]
class Solution {
public:
    int lenLongestFibSubseq(vector<int>& A) {
        vector<map<long, int>> dp(A.size());
        set<long> is_in;
        int ans = -1;
        for(int i=0; i<A.size(); i++){
            is_in.insert(A[i]);
            for(int j=0; j<i; j++){
                int d = A[i] - A[j];
                if ( find(begin(is_in), end(is_in), d) != end(is_in) && d < A[j]){
                    dp[i][A[j]] = dp[j][d] ? dp[j][d] + 1 : 2;
                    ans = max(ans, dp[i][A[j]]);
                }else{
                    dp[i][A[j]] = 2;
                }

            }
        }
        if(ans <= 2) return 0;
        return ans;}
};

fibonacci 思路

  1. 把数组A用集合st先存起来
  2. 每一次令a=A[i], b=A[j],因为是有序的,若满足fibonacci序列,则c=a+b必然在j位之后,可用st.count©判断是否可以继续向下传播
  3. 总之,就是一个fibonacci序列的求法过程

code

class Solution {
public:
int lenLongestFibSubseq(vector<int>& A) {
        unordered_set<int> st(begin(A), end(A));
        int ans = -1;
        for(int i=0; i<A.size(); i++){
            for(int j=i+1; j<A.size(); j++){
                int a = A[i];
                int b = A[j];
                int l = 2;
                while(st.count(a+b)){
                    b = a + b;
                    a = b - a;
                    l ++;
                }
                ans = max(ans, l);
            }
        }
        return ans > 2 ? ans : 0;
    }
};

2SUM 思路

参考

https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/discuss/165330/Java-beat-98-DP-%2B-2Sum

因为是排序的可以想到以下几种思路

  1. 二分查找
  2. 二数之和

此题就是对于Ai,在i之前找到二值之和为ai的两个位置l,r

dp[r][i]=dplr + 1

code

//
// Created by hanshan on 19-6-13.
//

#include <map>
#include <vector>
#include <set>
#include <unordered_set>
#include <algorithm>
using namespace std;
//[2,1,3,4,5,6,7,8]
class Solution {
public:
    int lenLongestFibSubseq(vector<int>& A) {
       vector<vector<int>> dp(A.size(), vector<int>(A.size()));
       int ans = -1;
       for(int i=2; i<A.size(); i++){
           int l = 0;
           int r = i-1;
           while(l < r){
               int sum = A[l] + A[r];
               if(sum < A[i]) l++;
               if(sum > A[i]) r--;
               if(sum == A[i]){
                   dp[r][i] = dp[l][r] + 1 ;
                   ans = max(ans, dp[r][i]);
                   l++;
                   r--;
               }
           }
       }
       return ans  ? ans + 2 : 0;
    }
};「
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值