写点什么

【LeetCode】最长的斐波那契子序列的长度 Java 题解

作者:Albert
  • 2022 年 7 月 15 日
  • 本文字数:1319 字

    阅读完需:约 4 分钟

题目描述

如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的:


n >= 3 对于所有 i + 2 <= n,都有 X_i + X_{i+1} = X_{i+2}给定一个严格递增的正整数数组形成序列 arr ,找到 arr 中最长的斐波那契式的子序列的长度。如果一个不存在,返回  0 。


(回想一下,子序列是从原序列 arr 中派生出来的,它从 arr 中删掉任意数量的元素(也可以不删),而不改变其余元素的顺序。例如, [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] 。
来源:力扣(LeetCode)链接:https://leetcode.cn/problems/length-of-longest-fibonacci-subsequence著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
复制代码

思路分析

  • 今天的算法题目是斐波那契式数组题目,斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)。

  • 理解了斐波那契数列的计算方式之后,题目要求求出最长的斐波那契式的子序列的长度,子序列不需要连续。

  • 首先可以想到的是朴素解法,我们遍历数组的中每一个元素,先确定两个元素,在按照斐波那契数列计算规则,计算下一个数值,如果下一个数值在给出的数组中,则长度至少为 3。在查找元素的时候,我们可以使用 hashMap 数据结构,提升查询效率。

  • 在朴素解法中,由于是双重循环遍历,有多余的重复计算。为了提升计算效率,我们可以采用记忆化的方式,缓存之前计算的结果。定义二维数组 memo, 缓存计算结果。memo[i][j] 表示 i, j 位置的斐波那契式数子序列的长度。具体实现代码如下,供参考。

通过代码

class Solution {    public int lenLongestFibSubseq(int[] arr) {        Map<Integer, Integer> map = new HashMap<Integer, Integer>();        int n = arr.length;        for (int i = 0; i < n; i++) {            map.put(arr[i], i);        }        int ans = 0;        int[][] memo = new int[n][n]; 
for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { int cnt = dfs(map, arr, i, j, memo); if (cnt >= 3) { ans = Math.max(cnt, ans); } } }
return ans; }
private int dfs(Map<Integer, Integer> map, int[] arr, int i, int j, int[][] memo){ if (memo[i][j] > 0) { return memo[i][j]; }
memo[i][j] = 2;
int next = arr[i] + arr[j]; if (map.containsKey(next)) { memo[i][j] = 1 + dfs(map, arr, j, map.get(next), memo); } return memo[i][j];
}}
复制代码

总结

  • 上述算法的时间复杂度是 O(n * n), 空间复杂度是 O(n)

  • 坚持算法每日一题,加油!

发布于: 刚刚阅读数: 4
用户头像

Albert

关注

还未添加个人签名 2019.09.29 加入

LeetCode,略懂后端的RD

评论

发布
暂无评论
【LeetCode】最长的斐波那契子序列的长度Java题解_LeetCode_Albert_InfoQ写作社区