ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-04-29 13:39:58  阅读:257  来源: 互联网

标签:契子 idx ++ 873 斐波 maxlen 序列 LeetCode dp


文章目录

1. 题目

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

  • n>=3n >= 3n>=3
  • 对于所有 i+2<=ni + 2 <= ni+2<=n,都有 Xi+Xi+1=Xi+2X_i + X_{i+1} = X_{i+2}Xi​+Xi+1​=Xi+2​

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

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

示例 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
  • 时间复杂度 O(n2log2n)O(n^2\log_2n)O(n2log2​n)
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)
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

标签:契子,idx,++,873,斐波,maxlen,序列,LeetCode,dp
来源: https://blog.csdn.net/qq_21201267/article/details/105821793

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有