69
69
70
70
### 方法一:动态规划
71
71
72
- - 状态表示:` dp[j][i] ` 表示斐波那契式最后两项为 ` arr[j] ` , ` arr[i] ` 时的最大子序列长度。
73
- - 状态计算:` dp[j][i] = dp[k][j] + 1 ` (当且仅当 ` k < j < i ` ,并且 ` arr[k] + arr[j] == arr[i] ` ), ` ans = max(ans, dp[j][i]) ` 。
72
+ 我们定义 $f[ i] [ j ] $ 表示以 $\textit{arr}[ i] $ 作为最后一个元素,以 $\textit{arr}[ j] $ 作为倒数第二个元素的最长斐波那契子序列的长度。初始时,对于任意的 $i \in [ 0, n)$ 和 $j \in [ 0, i)$,都有 $f[ i] [ j ] = 2$。其余的元素都是 $0$。
73
+
74
+ 我们用一个哈希表 $d$ 记录数组 $\textit{arr}$ 中每个元素对应的下标。
75
+
76
+ 然后,我们可以枚举 $\textit{arr}[ i] $ 和 $\textit{arr}[ j] $,其中 $i \in [ 2, n)$ 且 $j \in [ 1, i)$。假设当前枚举到的元素是 $\textit{arr}[ i] $ 和 $\textit{arr}[ j] $,我们可以得到 $\textit{arr}[ i] - \textit{arr}[ j] $,记作 $t$。如果 $t$ 在数组 $\textit{arr}$ 中,且 $t$ 的下标 $k$ 满足 $k < j$,那么我们可以得到一个以 $\textit{arr}[ j] $ 和 $\textit{arr}[ i] $ 作为最后两个元素的斐波那契子序列,其长度为 $f[ i] [ j ] = \max(f[ i] [ j ] , f[ j] [ k ] + 1)$。我们可以用这种方法不断更新 $f[ i] [ j ] $ 的值,然后更新答案。
77
+
78
+ 枚举结束后,返回答案即可。
79
+
80
+ 时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是数组 $\textit{arr}$ 的长度。
74
81
75
82
<!-- tabs:start -->
76
83
@@ -79,19 +86,19 @@ tags:
79
86
``` python
80
87
class Solution :
81
88
def lenLongestFibSubseq (self , arr : List[int ]) -> int :
82
- mp = {v: i for i, v in enumerate (arr)}
83
89
n = len (arr)
84
- dp = [[0 ] * n for _ in range (n)]
90
+ f = [[0 ] * n for _ in range (n)]
91
+ d = {x: i for i, x in enumerate (arr)}
85
92
for i in range (n):
86
93
for j in range (i):
87
- dp[j][i ] = 2
94
+ f[i][j ] = 2
88
95
ans = 0
89
- for i in range (n):
90
- for j in range (i):
91
- d = arr[i] - arr[j]
92
- if d in mp and (k := mp[d ]) < j:
93
- dp[j][i ] = max (dp[j][i ], dp[k][j ] + 1 )
94
- ans = max (ans, dp[j][i ])
96
+ for i in range (2 , n):
97
+ for j in range (1 , i):
98
+ t = arr[i] - arr[j]
99
+ if t in d and (k := d[t ]) < j:
100
+ f[i][j ] = max (f[i][j ], f[j][k ] + 1 )
101
+ ans = max (ans, f[i][j ])
95
102
return ans
96
103
```
97
104
@@ -101,26 +108,22 @@ class Solution:
101
108
class Solution {
102
109
public int lenLongestFibSubseq (int [] arr ) {
103
110
int n = arr. length;
104
- Map<Integer , Integer > mp = new HashMap<> ();
105
- for (int i = 0 ; i < n; ++ i) {
106
- mp. put(arr[i], i);
107
- }
108
- int [][] dp = new int [n][n];
111
+ int [][] f = new int [n][n];
112
+ Map<Integer , Integer > d = new HashMap<> ();
109
113
for (int i = 0 ; i < n; ++ i) {
114
+ d. put(arr[i], i);
110
115
for (int j = 0 ; j < i; ++ j) {
111
- dp[j][i ] = 2 ;
116
+ f[i][j ] = 2 ;
112
117
}
113
118
}
114
119
int ans = 0 ;
115
- for (int i = 0 ; i < n; ++ i) {
116
- for (int j = 0 ; j < i; ++ j) {
117
- int d = arr[i] - arr[j];
118
- if (mp. containsKey(d)) {
119
- int k = mp. get(d);
120
- if (k < j) {
121
- dp[j][i] = Math . max(dp[j][i], dp[k][j] + 1 );
122
- ans = Math . max(ans, dp[j][i]);
123
- }
120
+ for (int i = 2 ; i < n; ++ i) {
121
+ for (int j = 1 ; j < i; ++ j) {
122
+ int t = arr[i] - arr[j];
123
+ Integer k = d. get(t);
124
+ if (k != null && k < j) {
125
+ f[i][j] = Math . max(f[i][j], f[j][k] + 1 );
126
+ ans = Math . max(ans, f[i][j]);
124
127
}
125
128
}
126
129
}
@@ -135,23 +138,26 @@ class Solution {
135
138
class Solution {
136
139
public:
137
140
int lenLongestFibSubseq(vector<int >& arr) {
138
- unordered_map<int, int> mp;
139
141
int n = arr.size();
140
- for (int i = 0; i < n; ++i) mp[ arr[ i]] = i;
141
- vector<vector<int >> dp(n, vector<int >(n));
142
- for (int i = 0; i < n; ++i)
143
- for (int j = 0; j < i; ++j)
144
- dp[ j] [ i ] = 2;
145
- int ans = 0;
142
+ int f[ n] [ n ] ;
143
+ memset(f, 0, sizeof(f));
144
+ unordered_map<int, int> d;
146
145
for (int i = 0; i < n; ++i) {
146
+ d[ arr[ i]] = i;
147
147
for (int j = 0; j < i; ++j) {
148
- int d = arr[ i] - arr[ j] ;
149
- if (mp.count(d)) {
150
- int k = mp[ d] ;
151
- if (k < j) {
152
- dp[ j] [ i ] = max(dp[ j] [ i ] , dp[ k] [ j ] + 1);
153
- ans = max(ans, dp[ j] [ i ] );
154
- }
148
+ f[ i] [ j ] = 2;
149
+ }
150
+ }
151
+
152
+ int ans = 0;
153
+ for (int i = 2; i < n; ++i) {
154
+ for (int j = 1; j < i; ++j) {
155
+ int t = arr[i] - arr[j];
156
+ auto it = d.find(t);
157
+ if (it != d.end() && it->second < j) {
158
+ int k = it->second;
159
+ f[i][j] = max(f[i][j], f[j][k] + 1);
160
+ ans = max(ans, f[i][j]);
155
161
}
156
162
}
157
163
}
@@ -163,31 +169,92 @@ public:
163
169
#### Go
164
170
165
171
``` go
166
- func lenLongestFibSubseq(arr []int) int {
172
+ func lenLongestFibSubseq (arr []int ) ( ans int ) {
167
173
n := len (arr)
168
- mp := make(map[int ]int, n)
169
- for i, v := range arr {
170
- mp[v ] = i + 1
174
+ f := make ([][ ]int , n)
175
+ for i := range f {
176
+ f[i ] = make ([] int , n)
171
177
}
172
- dp := make([][]int, n)
173
- for i := 0; i < n; i++ {
174
- dp[i] = make([]int, n)
178
+
179
+ d := make (map [int ]int )
180
+ for i , x := range arr {
181
+ d[x] = i
175
182
for j := 0 ; j < i; j++ {
176
- dp[j][i ] = 2
183
+ f[i][j ] = 2
177
184
}
178
185
}
179
- ans := 0
180
- for i := 0; i < n; i++ {
181
- for j := 0; j < i; j++ {
182
- d := arr[i] - arr[j]
183
- k := mp[d] - 1
184
- if k >= 0 && k < j {
185
- dp[j][i] = max(dp[j][i], dp[k][j]+1)
186
- ans = max(ans, dp[j][i])
186
+
187
+ for i := 2 ; i < n; i++ {
188
+ for j := 1 ; j < i; j++ {
189
+ t := arr[i] - arr[j]
190
+ if k , ok := d[t]; ok && k < j {
191
+ f[i][j] = max (f[i][j], f[j][k]+1 )
192
+ ans = max (ans, f[i][j])
187
193
}
188
194
}
189
195
}
190
- return ans
196
+
197
+ return
198
+ }
199
+ ```
200
+
201
+ #### TypeScript
202
+
203
+ ``` ts
204
+ function lenLongestFibSubseq(arr : number []): number {
205
+ const n = arr .length ;
206
+ const f: number [][] = Array .from ({ length: n }, () => Array (n ).fill (0 ));
207
+ const d: Map <number , number > = new Map ();
208
+ for (let i = 0 ; i < n ; ++ i ) {
209
+ d .set (arr [i ], i );
210
+ for (let j = 0 ; j < i ; ++ j ) {
211
+ f [i ][j ] = 2 ;
212
+ }
213
+ }
214
+ let ans = 0 ;
215
+ for (let i = 2 ; i < n ; ++ i ) {
216
+ for (let j = 1 ; j < i ; ++ j ) {
217
+ const t = arr [i ] - arr [j ];
218
+ const k = d .get (t );
219
+ if (k !== undefined && k < j ) {
220
+ f [i ][j ] = Math .max (f [i ][j ], f [j ][k ] + 1 );
221
+ ans = Math .max (ans , f [i ][j ]);
222
+ }
223
+ }
224
+ }
225
+ return ans ;
226
+ }
227
+ ```
228
+
229
+ #### Rust
230
+
231
+ ``` rust
232
+ use std :: collections :: HashMap ;
233
+ impl Solution {
234
+ pub fn len_longest_fib_subseq (arr : Vec <i32 >) -> i32 {
235
+ let n = arr . len ();
236
+ let mut f = vec! [vec! [0 ; n ]; n ];
237
+ let mut d = HashMap :: new ();
238
+ for i in 0 .. n {
239
+ d . insert (arr [i ], i );
240
+ for j in 0 .. i {
241
+ f [i ][j ] = 2 ;
242
+ }
243
+ }
244
+ let mut ans = 0 ;
245
+ for i in 2 .. n {
246
+ for j in 1 .. i {
247
+ let t = arr [i ] - arr [j ];
248
+ if let Some (& k ) = d . get (& t ) {
249
+ if k < j {
250
+ f [i ][j ] = f [i ][j ]. max (f [j ][k ] + 1 );
251
+ ans = ans . max (f [i ][j ]);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ ans
257
+ }
191
258
}
192
259
```
193
260
@@ -199,25 +266,23 @@ func lenLongestFibSubseq(arr []int) int {
199
266
* @return {number}
200
267
*/
201
268
var lenLongestFibSubseq = function (arr ) {
202
- const mp = new Map ();
203
269
const n = arr .length ;
204
- const dp = new Array (n).fill (0 ).map (() => new Array (n).fill (0 ));
270
+ const f = Array .from ({ length: n }, () => Array (n).fill (0 ));
271
+ const d = new Map ();
205
272
for (let i = 0 ; i < n; ++ i) {
206
- mp .set (arr[i], i);
273
+ d .set (arr[i], i);
207
274
for (let j = 0 ; j < i; ++ j) {
208
- dp[j][i ] = 2 ;
275
+ f[i][j ] = 2 ;
209
276
}
210
277
}
211
278
let ans = 0 ;
212
- for (let i = 0 ; i < n; ++ i) {
213
- for (let j = 0 ; j < i; ++ j) {
214
- const d = arr[i] - arr[j];
215
- if (mp .has (d)) {
216
- const k = mp .get (d);
217
- if (k < j) {
218
- dp[j][i] = Math .max (dp[j][i], dp[k][j] + 1 );
219
- ans = Math .max (ans, dp[j][i]);
220
- }
279
+ for (let i = 2 ; i < n; ++ i) {
280
+ for (let j = 1 ; j < i; ++ j) {
281
+ const t = arr[i] - arr[j];
282
+ const k = d .get (t);
283
+ if (k !== undefined && k < j) {
284
+ f[i][j] = Math .max (f[i][j], f[j][k] + 1 );
285
+ ans = Math .max (ans, f[i][j]);
221
286
}
222
287
}
223
288
}
0 commit comments