题目描述:
如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的:
n >= 3 对于所有 i + 2 <= n,都有 X_i + X_{i+1} = X_{i+2}
给定一个严格递增的正整数数组形成序列,找到 A 中最长的斐波那契式的子序列的长度。如果一个不存在,返回 0 。
解题思路:
以 [1,2,3,4,5,6,7,8] 为例
我们需要准备一个HashSet把数组中所有的值存放进去。 代码如下
HashSet<Integer> set = new HashSet<>(); for(int i=0;i<A.length;i++){ set.add(A[i]); }
解题的关键在于,我们要从这些数字中找出满足X_i + X_{i+1} = X_{i+2} 这个关系的序列,那么我们知道了i 和 i+1的值,那么i+2的值必须为 i的值加上i+1的值
好像是一句废话…… 但是这就是我们为什么需要准备一个HashSet的原因,因为我们可以先双层遍历,遍历所有的i 和 i+1 的组合,比如:1、2;1、3; 1,4
...... 2、3;2,4 等等所有的组合,代码如下
for(int i=0;i<A.length;i++){ for(int j=i+1;j<A.length;j++){ }
}
有了组合 我们便可以判断这个组合的下个数,即 X_i + X_{i+1} = X_{i+2} 中的X_{i+2} 是否在HashSet中,如果在,那么这个数
加上,前面两个数的组合,就可以构成一个满足条件的子序列。当然要注意,当下个数在HashSet的集合中时候,我们还要继续往下判断,看这个新的数 与 上个数X_{i+1}构成一个组合
下个满足条件的数,是否在HashSet中,如果在,就说明这个子序列还可以继续延伸。核心代码如下
// 这里的x y 就是一个组合 x+y 就是满足条件的下个数,判断其是否在set集合里 // 如果在,则继续判断。 while(set.contains(x+y)){ int temp = x + y; x = y; y = temp; len ++; }
完整代码如下:
class Solution { public int lenLongestFibSubseq(int[] A) { HashSet<Integer> set = new HashSet<>(); for(int i=0;i<A.length;i++){ set.add(A[i]); } int result = 0; for(int i=0;i<A.length;i++){ for(int j=i+1;j<A.length;j++){ int len = 2; int x = A[i]; int y = A[j]; while(set.contains(x+y)){ int temp = x + y; x = y; y = temp; len ++; } result = Math.max(result,len); } } return result <= 2 ? 0 : result; } }