leetcode
leetcode 751 ~ 800
最长的斐波那契子序列的长度

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

难度:

标签:

题目描述

代码结果

运行时间: 211 ms, 内存: 16.5 MB


/*
 * 思路:
 * 1. 使用 Java Stream API 的特性,先将数组转换为列表以方便操作。
 * 2. 使用哈希表存储元素的索引。
 * 3. 双重 for 循环迭代每一对可能的末尾元素,
 *    通过 lambda 表达式和过滤器来查找前一个元素是否存在。
 * 4. 更新 dp 数组和最大长度。
 */

import java.util.*;

public class FibonacciSubsequenceStream {
    public int lenLongestFibSubseq(int[] arr) {
        Map<Integer, Integer> index = new HashMap<>();
        Arrays.stream(arr).forEach(i -> index.put(i, Arrays.binarySearch(arr, i)));
        int[][] dp = new int[arr.length][arr.length];
        int maxLength = 0;

        for (int j = 1; j < arr.length; j++) {
            for (int i = 0; i < j; i++) {
                int k = index.getOrDefault(arr[j] - arr[i], -1);
                if (k >= 0 && k < i) {
                    dp[i][j] = dp[k][i] + 1;
                    maxLength = Math.max(maxLength, dp[i][j] + 2);
                }
            }
        }

        return maxLength >= 3 ? maxLength : 0;
    }
}

解释

方法:

该题解的主要思路是通过双层循环枚举所有可能的斐波那契序列的前两个元素,然后使用散列表来快速查找序列中的下一个元素。首先,使用一个字典将数组中的所有数字存储起来,用于后续的快速查找。对于数组中的每一对元素 (arr[j], arr[i]),将其视为可能的斐波那契序列的前两个数,然后尝试构建斐波那契序列并计算其长度。如果序列长度大于2,则更新最大长度。这种方法直接根据斐波那契序列的定义,不断查找和更新可能的序列长度,直到无法继续构建为止。

时间复杂度:

O(n^2)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在寻找最长斐波那契子序列时选择从第二个元素开始遍历?
在寻找最长斐波那契子序列的过程中,每个斐波那契序列至少需要两个元素作为起始点,即序列的前两个数。从第二个元素开始遍历是为了确保可以选择这两个起始元素。第一个元素前面没有其他元素,因此如果从第一个元素开始,我们无法形成至少包含两个元素的斐波那契式序列。从第二个元素开始可以确保每次迭代都有可能选取一对元素作为斐波那契序列的起始两个数。
🦆
在该算法中,字典用于存储数组元素和标记,具体是如何利用字典进行快速查找的?
在算法实现中,字典被用作快速查找表来判断序列中的某个数字是否存在于原始数组中。每个数组元素作为键,其存在性(标记为1)作为值存入字典。这样,在构建斐波那契序列时,可以在O(1)时间复杂度内直接通过字典查找判断下一个斐波那契数是否存在,而不需要进行线性搜索,从而大幅提高了查找效率和整体算法的性能。
🦆
算法中提到的更新斐波那契序列长度(cnt)的逻辑是否考虑了所有可能的子序列,还是只专注于当前枚举的两个元素作为起始点?
该算法只专注于当前枚举的两个元素作为斐波那契序列的起始点,并基于这两个点尝试构建和延伸序列。对于每一对可能的起始元素,算法计算以它们为开头的斐波那契序列的最大长度。虽然算法确实枚举了所有可能的起始点对,但它并不会在同一时间内考虑多个不同起点的序列组合。因此,每次更新序列长度时,只考虑了从当前选定的起始点扩展出去的序列。

相关问题

斐波那契数

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 01 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

给定 n ,请计算 F(n)

 

示例 1:

输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1

示例 2:

输入:n = 3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2

示例 3:

输入:n = 4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3

 

提示:

  • 0 <= n <= 30