给定一个严格增加的正整数数组A ,其中,
。任务是找到A的最长斐波那契式子序列的长度。如果不存在此子序列,则返回0 。
例子:
Input: A = [1, 3, 7, 11, 12, 14, 18]
Output: 3
Explanation:
The longest subsequence that is Fibonacci-like: [1, 11, 12]. Other possible subsequences are [3, 11, 14] or [7, 11, 18].
Input: A = [1, 2, 3, 4, 5, 6, 7, 8]
Output: 5
Explanation:
The longest subsequence that is Fibonacci-like: [1, 2, 3, 5, 8].
幼稚的方法:类似斐波那契的序列,使得每个序列都有两个相邻的项来确定下一个预期项。
For example, with 1, 1, we expect that the sequence must continue 2, 3, 5, 8, 13, … and so on.
- 使用Set或Map快速确定数组A中是否存在下一个斐波那契数列。由于这些术语的指数增长,每次迭代将只获得log(M)搜索以获取下一个元素。
- 对于每个起始对A [i],A [j] ,我们维持下一个期望值y = A [i] + A [j]和先前看到的最大值x = A [j] 。如果y在数组中,则可以更新这些值(x,y)->(y,x + y),否则我们将立即停止。
下面是上述方法的实现:
C++
// CPP implementation of above approach
#include
using namespace std;
// Function to return the max Length of
// Fibonacci subsequence
int LongestFibSubseq(int A[], int n)
{
// Store all array elements in a hash
// table
unordered_set S(A, A + n);
int maxLen = 0, x, y;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
x = A[j];
y = A[i] + A[j];
int length = 2;
// check until next fib element is found
while (S.find(y) != S.end()) {
// next element of fib subseq
int z = x + y;
x = y;
y = z;
maxLen = max(maxLen, ++length);
}
}
}
return maxLen >= 3 ? maxLen : 0;
}
// Driver program
int main()
{
int A[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int n = sizeof(A) / sizeof(A[0]);
cout << LongestFibSubseq(A, n);
return 0;
}
// This code is written by Sanjit_Prasad
Java
// Java implementation of above approach
import java.util.*;
public class GFG {
// Function to return the max Length of
// Fibonacci subsequence
static int LongestFibSubseq(int A[], int n) {
// Store all array elements in a hash
// table
TreeSet S = new TreeSet<>();
for (int t : A) {
// Add each element into the set
S.add(t);
}
int maxLen = 0, x, y;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
x = A[j];
y = A[i] + A[j];
int length = 3;
// check until next fib element is found
while (S.contains(y) && (y != S.last())) {
// next element of fib subseq
int z = x + y;
x = y;
y = z;
maxLen = Math.max(maxLen, ++length);
}
}
}
return maxLen >= 3 ? maxLen : 0;
}
// Driver program
public static void main(String[] args) {
int A[] = {1, 2, 3, 4, 5, 6, 7, 8};
int n = A.length;
System.out.print(LongestFibSubseq(A, n));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the
# above approach
# Function to return the max Length
# of Fibonacci subsequence
def LongestFibSubseq(A, n):
# Store all array elements in
# a hash table
S = set(A)
maxLen = 0
for i in range(0, n):
for j in range(i + 1, n):
x = A[j]
y = A[i] + A[j]
length = 2
# check until next fib
# element is found
while y in S:
# next element of fib subseq
z = x + y
x = y
y = z
length += 1
maxLen = max(maxLen, length)
return maxLen if maxLen >= 3 else 0
# Driver Code
if __name__ == "__main__":
A = [1, 2, 3, 4, 5, 6, 7, 8]
n = len(A)
print(LongestFibSubseq(A, n))
# This code is contributed
# by Rituraj Jain
C#
// C# implementation of above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to return the max Length of
// Fibonacci subsequence
static int LongestFibSubseq(int []A, int n)
{
// Store all array elements in a hash
// table
SortedSet S = new SortedSet();
foreach (int t in A)
{
// Add each element into the set
S.Add(t);
}
int maxLen = 0, x, y;
for (int i = 0; i < n; ++i)
{
for (int j = i + 1; j < n; ++j)
{
x = A[j];
y = A[i] + A[j];
int length = 3;
// check until next fib element is found
while (S.Contains(y) && y != last(S))
{
// next element of fib subseq
int z = x + y;
x = y;
y = z;
maxLen = Math.Max(maxLen, ++length);
}
}
}
return maxLen >= 3 ? maxLen : 0;
}
static int last(SortedSet S)
{
int ans = 0;
foreach(int a in S)
ans = a;
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int []A = {1, 2, 3, 4, 5, 6, 7, 8};
int n = A.Length;
Console.Write(LongestFibSubseq(A, n));
}
}
// This code is contributed by 29AjayKumar
C++
// CPP program for the above approach
#include
using namespace std;
// Function to return the max Length of
// Fibonacci subsequence
int LongestFibSubseq(int A[], int n)
{
// Initialize the unordered map
unordered_map m;
int N = n, res = 0;
// Initialize dp table
int dp[N][N];
// Iterate till N
for (int j = 0; j < N; ++j) {
m[A[j]] = j;
for (int i = 0; i < j; ++i) {
// Check if the current integer
// forms a finonacci sequence
int k = m.find(A[j] - A[i]) == m.end()
? -1
: m[A[j] - A[i]];
// Update the dp table
dp[i][j] = (A[j] - A[i] < A[i] && k >= 0)
? dp[k][i] + 1
: 2;
res = max(res, dp[i][j]);
}
}
// Return the answer
return res > 2 ? res : 0;
}
// Driver program
int main()
{
int A[] = { 1, 3, 7, 11, 12, 14, 18 };
int n = sizeof(A) / sizeof(A[0]);
cout << LongestFibSubseq(A, n);
return 0;
}
5
时间复杂度: O(N 2 * log(M)),其中N是数组的长度,M是max(A)。
高效方法:为了优化上述方法,其思想是实施动态编程。初始化代表斐波那契序列长度的dp表dp [a,b]以(a,b)结尾。然后将表更新为dp [a,b] =(dp [b – a,a] + 1)或2
下面是上述方法的实现:
C++
// CPP program for the above approach
#include
using namespace std;
// Function to return the max Length of
// Fibonacci subsequence
int LongestFibSubseq(int A[], int n)
{
// Initialize the unordered map
unordered_map m;
int N = n, res = 0;
// Initialize dp table
int dp[N][N];
// Iterate till N
for (int j = 0; j < N; ++j) {
m[A[j]] = j;
for (int i = 0; i < j; ++i) {
// Check if the current integer
// forms a finonacci sequence
int k = m.find(A[j] - A[i]) == m.end()
? -1
: m[A[j] - A[i]];
// Update the dp table
dp[i][j] = (A[j] - A[i] < A[i] && k >= 0)
? dp[k][i] + 1
: 2;
res = max(res, dp[i][j]);
}
}
// Return the answer
return res > 2 ? res : 0;
}
// Driver program
int main()
{
int A[] = { 1, 3, 7, 11, 12, 14, 18 };
int n = sizeof(A) / sizeof(A[0]);
cout << LongestFibSubseq(A, n);
return 0;
}
3
时间复杂度: O(N 2 ),其中N是数组的长度。