LeetCode 题解工作台

最长的斐波那契子序列的长度

如果序列 x 1 , x 2 , ..., x n 满足下列条件,就说它是 斐波那契式 的: n >= 3 对于所有 i + 2 ,都有 x i + x i+1 == x i+2 给定一个 严格递增 的正整数数组形成序列 arr ,找到 arr 中最长的斐波那契式的子序列的长度。如果不存在,返回 0…

category

3

题型

code_blocks

7

代码语言

hub

3

相关题

当前训练重点

中等 · 数组·哈希·扫描

bolt

答案摘要

我们定义 表示以 作为最后一个元素,以 作为倒数第二个元素的最长斐波那契子序列的长度。初始时,对于任意的 $i \in [0, n)$ 和 $j \in [0, i)$,都有 $f[i][j] = 2$。其余的元素都是 。 我们用一个哈希表 记录数组 中每个元素对应的下标。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 数组·哈希·扫描 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

如果序列 x1, x2, ..., xn 满足下列条件,就说它是 斐波那契式 的:

  • n >= 3
  • 对于所有 i + 2 <= n,都有 xi + xi+1 == xi+2

给定一个 严格递增 的正整数数组形成序列 arr ,找到 arr 中最长的斐波那契式的子序列的长度。如果不存在,返回  0

子序列 是通过从另一个序列 arr 中删除任意数量的元素(包括删除 0 个元素)得到的,同时不改变剩余元素顺序。例如,[3, 5, 8][3, 4, 5, 6, 7, 8] 的子序列。

 

示例 1:

输入: arr = [1,2,3,4,5,6,7,8]
输出: 5
解释: 最长的斐波那契式子序列为 [1,2,3,5,8] 。

示例 2:

输入: arr = [1,3,7,11,12,14,18]
输出: 3
解释: 最长的斐波那契式子序列有 [1,11,12]、[3,11,14] 以及 [7,11,18] 。

 

提示:

  • 3 <= arr.length <= 1000
  • 1 <= arr[i] < arr[i + 1] <= 109

lightbulb

解题思路

方法一:动态规划

我们定义 f[i][j]f[i][j] 表示以 arr[i]\textit{arr}[i] 作为最后一个元素,以 arr[j]\textit{arr}[j] 作为倒数第二个元素的最长斐波那契子序列的长度。初始时,对于任意的 i[0,n)i \in [0, n)j[0,i)j \in [0, i),都有 f[i][j]=2f[i][j] = 2。其余的元素都是 00

我们用一个哈希表 dd 记录数组 arr\textit{arr} 中每个元素对应的下标。

然后,我们可以枚举 arr[i]\textit{arr}[i]arr[j]\textit{arr}[j],其中 i[2,n)i \in [2, n)j[1,i)j \in [1, i)。假设当前枚举到的元素是 arr[i]\textit{arr}[i]arr[j]\textit{arr}[j],我们可以得到 arr[i]arr[j]\textit{arr}[i] - \textit{arr}[j],记作 tt。如果 tt 在数组 arr\textit{arr} 中,且 tt 的下标 kk 满足 k<jk < j,那么我们可以得到一个以 arr[j]\textit{arr}[j]arr[i]\textit{arr}[i] 作为最后两个元素的斐波那契子序列,其长度为 f[i][j]=max(f[i][j],f[j][k]+1)f[i][j] = \max(f[i][j], f[j][k] + 1)。我们可以用这种方法不断更新 f[i][j]f[i][j] 的值,然后更新答案。

枚举结束后,返回答案即可。

时间复杂度 O(n2)O(n^2),空间复杂度 O(n2)O(n^2)。其中 nn 是数组 arr\textit{arr} 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution:
    def lenLongestFibSubseq(self, arr: List[int]) -> int:
        n = len(arr)
        f = [[0] * n for _ in range(n)]
        d = {x: i for i, x in enumerate(arr)}
        for i in range(n):
            for j in range(i):
                f[i][j] = 2
        ans = 0
        for i in range(2, n):
            for j in range(1, i):
                t = arr[i] - arr[j]
                if t in d and (k := d[t]) < j:
                    f[i][j] = max(f[i][j], f[j][k] + 1)
                    ans = max(ans, f[i][j])
        return ans
speed

复杂度分析

指标
时间O(n^2)
空间O(n^2)
psychology

面试官常问的追问

外企场景
  • question_mark

    Can the candidate leverage dynamic programming efficiently for this problem?

  • question_mark

    Does the candidate recognize the importance of using a hash table for faster lookup?

  • question_mark

    Can the candidate explain the Fibonacci-like structure and how it applies to subsequences?

warning

常见陷阱

外企场景
  • error

    Not considering all pairs of elements, which can miss valid subsequences.

  • error

    Misunderstanding the Fibonacci-like condition, leading to incorrect subsequences.

  • error

    Not optimizing the lookup with a hash table, which increases time complexity unnecessarily.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Variation with unsorted arrays: Can the approach be adjusted to handle non-strictly increasing arrays?

  • arrow_right_alt

    Variation with larger inputs: How would the algorithm scale if the array length increased significantly beyond 1000?

  • arrow_right_alt

    Variation with multiple valid subsequences: How to handle cases where there are multiple Fibonacci-like subsequences with the same length?

help

常见问题

外企场景

最长的斐波那契子序列的长度题解:数组·哈希·扫描 | LeetCode #873 中等