LeetCode 剑指 Offer II 093. 最长斐波那契数列

一只小逸白 2022-01-27 21:01:34

题目:

如果序列 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] 。
示例1:

输入: 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] <= 10^9

思路:

动态规划 + 哈希表
下标i j k成立,我们将j k存入dp里,值为i j 为结尾的序列前面的个数 + 1
总结:如果 (i, j)(j, k) 是连通的, dp[j, k] = dp[i, j] + 1
arr = [1,2,3,4,5,6,7,8],子序列为 [1,2,3,5,8]
此时j k指向5 8的话,dp[5,8] = dp[3, 5] + 1 = d[2,3] + 1 + 1 = dp[1,2] + 1 + 1 + 1 = 3

class Solution {
public:
    int lenLongestFibSubseq(vector<int>& arr) {
        int n = arr.size();
        unordered_map<int, int> index;
        for(int i = 0; i < n; i++) {
            index[arr[i]] = i;
        }
        // 保存dp[j*n+k],值表示j k 序列前面的个数
        unordered_map<int, int> dp;
        int ans = 0;
        for(int k = 0; k < n; k++) {
            for(int j = 0; j < k; j++) {
                // i存在并且i < j,防止i j取两边,保证 i < j
                if(index.count(arr[k] - arr[j]) && index[arr[k] - arr[j]] < j) {
                    int i = index[arr[k] - arr[j]];
                    dp[j * n + k] = dp[i * n + j] + 1;
                    // j k前面个数加上 j k两个数
                    ans = max(ans, dp[j * n + k] + 2);
                }
            }
        }
        return ans;
    }
};
...全文
47 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
发帖
Java全栈抱团学习社区
加入

6.7w+

社区成员

欢迎大家来到抱团内卷学习社区,在这里大家可以分享自己的学习笔记,求职心得,一起记录彼此的成长历程。社区群号:94108843,WX公众号:【兴趣使然的草帽路飞】
社区管理员
  • 兴趣使然的草帽路飞
  • 一百个Chocolate
  • 灰小猿
帖子事件
创建了帖子
2022-01-27 21:01
社区公告

最怕你一生碌碌无为,还安慰自己平凡可贵!

努力提高自己的知识储备,助力每一位冲刺大厂的小伙伴!

祝大家前程似锦,offer连连!

注意:每个月活跃积分最高的小伙伴,可以获得社区管理员权限哦!