前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 873. 最长的斐波那契子序列的长度(动态规划)

LeetCode 873. 最长的斐波那契子序列的长度(动态规划)

作者头像
Michael阿明
发布2020-07-13 12:00:30
7750
发布2020-07-13 12:00:30
举报

1. 题目

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

(回想一下,子序列是从原序列 A 中派生出来的,它从 A 中删掉任意数量的元素(也可以不删),而不改变其余元素的顺序。例如, [3, 5, 8] 是 [3, 4, 5, 6, 7, 8] 的一个子序列)

代码语言:javascript
复制
示例 1:
输入: [1,2,3,4,5,6,7,8]
输出: 5
解释:
最长的斐波那契式子序列为:[1,2,3,5,8] 。

示例 2:
输入: [1,3,7,11,12,14,18]
输出: 3
解释:
最长的斐波那契式子序列有:
[1,11,12],[3,11,14] 以及 [7,11,18] 。
 
提示:
3 <= A.length <= 1000
1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 暴力解

  • 以两个点为基准,生成斐波那契数列,在set中查找是否找到生成的数,记录最大 len
代码语言:javascript
复制
class Solution {
public:
    int lenLongestFibSubseq(vector<int>& A) {
    	unordered_set<int> s;
    	for(int Ai : A)
    		s.insert(Ai);
    	int a, b, c, len = 0, maxlen = 0;
    	for(int i = 0, j; i < A.size(); ++i)
    	{
    		for(j = i+1; j < A.size(); ++j)
    		{
                len = 2;
    			c = A[i]+A[j];
                a = A[i];
                b = A[j];
				while(s.count(c))
				{
					len++;
					maxlen = max(maxlen, len);
					a = b;
					b = c;
					c = a+b;
				}
    		}
    	}
    	return maxlen;
    }
};

384 ms 9 MB

2.2 动态规划

  • dp[i][j] 表示以 A[i],A[j]结尾的序列长度
  • 初始化所有可能的dp[i][j] = 2, i < j
  • 预先将A的数值和 idx 插入哈希map,方便后面查找
  • 对于 i, j 结尾的序列,其前一位数应该是 A[j]-A[i],查找其是否存在与哈希表中
  • 如果存在,且其 idx < idx_i ,可以把前面的A[idx],A[i]结尾的序列跟 A[j]组成更长的序列,则 dp[i][j] = max(dp[i][j],dp[idx][i]+1)
代码语言:javascript
复制
class Solution {
public:
    int lenLongestFibSubseq(vector<int>& A) {
    	unordered_map<int,int> m;//val, idx
        int i, j, prevAi, idx, maxlen = 0, n = A.size();
    	for(i = 0; i < n; ++i)
    		m[A[i]] = i;
    	vector<vector<int>> dp(n,vector<int>(n,0));
    	//dp[i][j] 表示以 A[i],A[j]结尾的序列长度
    	for(i = 0; i < n; ++i)
    		for(j = i+1; j < n; ++j)
    			dp[i][j] = 2;
    	for(i = 0; i < A.size(); ++i)
    	{
    		for(j = i+1; j < A.size(); ++j)
    		{
    			prevAi = A[j]-A[i];//A[i] 前一位数
                if(m.count(prevAi))
                {
                	idx = m[prevAi];//前一位数下标
                	if(idx < i)//在 i 前面
                	{
                        dp[i][j] = max(dp[i][j],dp[idx][i]+1);//更长的序列
                        maxlen = max(maxlen,dp[i][j]);
                    }
                }
    		}
    	}
    	return maxlen;
    }
};

416 ms 61.9 MB

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
  • 2. 解题
    • 2.1 暴力解
      • 2.2 动态规划
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档