标签: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 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.
(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 思路
- 和1027 longest arithmetic sequence的思路一样,但是直接用的话,会TLE
- 注意数组是上升的序列,还在思考怎么解决
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 思路
- 把数组A用集合st先存起来
- 每一次令a=A[i], b=A[j],因为是有序的,若满足fibonacci序列,则c=a+b必然在j位之后,可用st.count©判断是否可以继续向下传播
- 总之,就是一个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 思路
参考
因为是排序的可以想到以下几种思路
- 二分查找
- 二数之和
此题就是对于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;
}
};「