Skip to content

Commit adad915

Browse files
authored
feat: add solutions to lc problem: No.0873 (doocs#3255)
No.0873.Length of Longest Fibonacci Subsequence
1 parent 98abe13 commit adad915

File tree

9 files changed

+388
-207
lines changed

9 files changed

+388
-207
lines changed

solution/0800-0899/0873.Length of Longest Fibonacci Subsequence/README.md

Lines changed: 135 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,15 @@ tags:
6969

7070
### 方法一:动态规划
7171

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}$ 的长度。
7481

7582
<!-- tabs:start -->
7683

@@ -79,19 +86,19 @@ tags:
7986
```python
8087
class Solution:
8188
def lenLongestFibSubseq(self, arr: List[int]) -> int:
82-
mp = {v: i for i, v in enumerate(arr)}
8389
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)}
8592
for i in range(n):
8693
for j in range(i):
87-
dp[j][i] = 2
94+
f[i][j] = 2
8895
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])
95102
return ans
96103
```
97104

@@ -101,26 +108,22 @@ class Solution:
101108
class Solution {
102109
public int lenLongestFibSubseq(int[] arr) {
103110
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<>();
109113
for (int i = 0; i < n; ++i) {
114+
d.put(arr[i], i);
110115
for (int j = 0; j < i; ++j) {
111-
dp[j][i] = 2;
116+
f[i][j] = 2;
112117
}
113118
}
114119
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]);
124127
}
125128
}
126129
}
@@ -135,23 +138,26 @@ class Solution {
135138
class Solution {
136139
public:
137140
int lenLongestFibSubseq(vector<int>& arr) {
138-
unordered_map<int, int> mp;
139141
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;
146145
for (int i = 0; i < n; ++i) {
146+
d[arr[i]] = i;
147147
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]);
155161
}
156162
}
157163
}
@@ -163,31 +169,92 @@ public:
163169
#### Go
164170

165171
```go
166-
func lenLongestFibSubseq(arr []int) int {
172+
func lenLongestFibSubseq(arr []int) (ans int) {
167173
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)
171177
}
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
175182
for j := 0; j < i; j++ {
176-
dp[j][i] = 2
183+
f[i][j] = 2
177184
}
178185
}
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])
187193
}
188194
}
189195
}
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+
}
191258
}
192259
```
193260

@@ -199,25 +266,23 @@ func lenLongestFibSubseq(arr []int) int {
199266
* @return {number}
200267
*/
201268
var lenLongestFibSubseq = function (arr) {
202-
const mp = new Map();
203269
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();
205272
for (let i = 0; i < n; ++i) {
206-
mp.set(arr[i], i);
273+
d.set(arr[i], i);
207274
for (let j = 0; j < i; ++j) {
208-
dp[j][i] = 2;
275+
f[i][j] = 2;
209276
}
210277
}
211278
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]);
221286
}
222287
}
223288
}

0 commit comments

Comments
 (0)