若是序列 X_1, X_2, ..., X_n 知足下列條件,就說它是 斐波那契式 的:算法
n >= 3
對於全部 i + 2 <= n,都有 X_i + X_{i+1} = X_{i+2}
給定一個嚴格遞增的正整數數組造成序列,找到 A 中最長的斐波那契式的子序列的長度。若是一個不存在,返回 0 。數組
(回想一下,子序列是從原序列 A 中派生出來的,它從 A 中刪掉任意數量的元素(也能夠不刪),而不改變其他元素的順序。例如, [3, 5, 8] 是 [3, 4, 5, 6, 7, 8] 的一個子序列)code
示例 1:索引
輸入: [1,2,3,4,5,6,7,8]
輸出: 5
解釋:
最長的斐波那契式子序列爲:[1,2,3,5,8] 。
示例 2:three
輸入: [1,3,7,11,12,14,18]
輸出: 3
解釋:
最長的斐波那契式子序列有:
[1,11,12],[3,11,14] 以及 [7,11,18] 。get
若是直接使用遍歷算法的話,時間複雜度大概是O(n^3)這個數量級,而題目要求中給出的數組A的最大長度爲1000,若是使用O(n^3)的算法,勢必會超時。
考慮如何簡化:斐波那契數列有一個性質,即一但前兩個數字肯定,整個數列即肯定的。故咱們使用二維數組來存儲這一信息, 二維數組map的兩個索引分別爲該斐波那契數列前兩個數在A中的索引,其對應的值爲由該數列在整個序列中的最大長度。
咱們只要從後往前遍歷整個數組,就能使用到map中所儲存的信息,具體代碼以下:io
代碼:class
class Solution { public int lenLongestFibSubseq(int[] A) { int res = 0; // HashMap<Integer, Integer []> map = new HashMap<Integer, Integer[]>(); int [][] map = new int [A.length][A.length]; map[A.length- 2][A.length -1] = 2; // List <Integer> list = new ArrayList<>(); // for(int i = 0 ; i < A.length ; i++){ // list.add(A[i]); // } for(int j = A.length - 3; j >= 0; j--){ for(int i = j + 1; i <A.length; i++){ int three = A[j] + A[i]; int index = findIndex(i, three , A); if(index != -1) { map[j][i] = map[i][index] +1; res = Math.max(map[j][i], res); }else{ map[j][i] = 2; } } } return res < 3 ? 0: res; } public int findIndex(int start, int target, int [] A) { int end = A.length -1; while(start <= end) { int mid = (start + end) / 2; if(A[mid] < target) { start = mid +1; }else if(A[mid] > target) { end = mid - 1; }else { return mid; } } return -1; } }