给定一个严格递增的正整数数组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
Javascript
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 是数组的长度。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。