Skip to content

Commit 29c9339

Browse files
authored
feat: add solutions to lc problems: No.3176,3177 (doocs#3092)
* No.3176.Find the Maximum Length of a Good Subsequence I * No.3177.Find the Maximum Length of a Good Subsequence II
1 parent ee9a1b2 commit 29c9339

File tree

14 files changed

+1418
-14
lines changed

14 files changed

+1418
-14
lines changed

solution/3100-3199/3176.Find the Maximum Length of a Good Subsequence I/README.md

+347-3
Original file line numberDiff line numberDiff line change
@@ -64,32 +64,376 @@ tags:
6464

6565
<!-- solution:start -->
6666

67-
### 方法一
67+
### 方法一:动态规划
68+
69+
我们定义 $f[i][h]$ 表示以 $nums[i]$ 结尾,且有不超过 $h$ 个下标满足条件的最长好子序列的长度。初始时 $f[i][h] = 1$。答案为 $\max(f[i][k])$,其中 $0 \le i < n$。
70+
71+
我们考虑如何计算 $f[i][h]$。我们可以枚举 $0 \le j < i$,如果 $nums[i] = nums[j]$,那么 $f[i][h] = \max(f[i][h], f[j][h] + 1)$;否则如果 $h > 0$,那么 $f[i][h] = \max(f[i][h], f[j][h - 1] + 1)$。即:
72+
73+
$$
74+
f[i][h]=
75+
\begin{cases}
76+
\max(f[i][h], f[j][h] + 1), & \text{if } nums[i] = nums[j], \\
77+
\max(f[i][h], f[j][h - 1] + 1), & \text{if } h > 0.
78+
\end{cases}
79+
$$
80+
81+
最终答案为 $\max(f[i][k])$,其中 $0 \le i < n$。
82+
83+
时间复杂度 $O(n^2 \times k)$,空间复杂度 $O(n \times k)$。其中 $n$ 是数组 `nums` 的长度。
6884

6985
<!-- tabs:start -->
7086

7187
#### Python3
7288

7389
```python
74-
90+
class Solution:
91+
def maximumLength(self, nums: List[int], k: int) -> int:
92+
n = len(nums)
93+
f = [[1] * (k + 1) for _ in range(n)]
94+
ans = 0
95+
for i, x in enumerate(nums):
96+
for h in range(k + 1):
97+
for j, y in enumerate(nums[:i]):
98+
if x == y:
99+
f[i][h] = max(f[i][h], f[j][h] + 1)
100+
elif h:
101+
f[i][h] = max(f[i][h], f[j][h - 1] + 1)
102+
ans = max(ans, f[i][k])
103+
return ans
75104
```
76105

77106
#### Java
78107

79108
```java
80-
109+
class Solution {
110+
public int maximumLength(int[] nums, int k) {
111+
int n = nums.length;
112+
int[][] f = new int[n][k + 1];
113+
int ans = 0;
114+
for (int i = 0; i < n; ++i) {
115+
for (int h = 0; h <= k; ++h) {
116+
for (int j = 0; j < i; ++j) {
117+
if (nums[i] == nums[j]) {
118+
f[i][h] = Math.max(f[i][h], f[j][h]);
119+
} else if (h > 0) {
120+
f[i][h] = Math.max(f[i][h], f[j][h - 1]);
121+
}
122+
}
123+
++f[i][h];
124+
}
125+
ans = Math.max(ans, f[i][k]);
126+
}
127+
return ans;
128+
}
129+
}
81130
```
82131

83132
#### C++
84133

85134
```cpp
135+
class Solution {
136+
public:
137+
int maximumLength(vector<int>& nums, int k) {
138+
int n = nums.size();
139+
int f[n][k + 1];
140+
memset(f, 0, sizeof(f));
141+
int ans = 0;
142+
for (int i = 0; i < n; ++i) {
143+
for (int h = 0; h <= k; ++h) {
144+
for (int j = 0; j < i; ++j) {
145+
if (nums[i] == nums[j]) {
146+
f[i][h] = max(f[i][h], f[j][h]);
147+
} else if (h) {
148+
f[i][h] = max(f[i][h], f[j][h - 1]);
149+
}
150+
}
151+
++f[i][h];
152+
}
153+
ans = max(ans, f[i][k]);
154+
}
155+
return ans;
156+
}
157+
};
158+
```
159+
160+
#### Go
161+
162+
```go
163+
func maximumLength(nums []int, k int) (ans int) {
164+
f := make([][]int, len(nums))
165+
for i := range f {
166+
f[i] = make([]int, k+1)
167+
}
168+
for i, x := range nums {
169+
for h := 0; h <= k; h++ {
170+
for j, y := range nums[:i] {
171+
if x == y {
172+
f[i][h] = max(f[i][h], f[j][h])
173+
} else if h > 0 {
174+
f[i][h] = max(f[i][h], f[j][h-1])
175+
}
176+
}
177+
f[i][h]++
178+
}
179+
ans = max(ans, f[i][k])
180+
}
181+
return
182+
}
183+
```
184+
185+
#### TypeScript
186+
187+
```ts
188+
function maximumLength(nums: number[], k: number): number {
189+
const n = nums.length;
190+
const f: number[][] = Array.from({ length: n }, () => Array(k + 1).fill(0));
191+
let ans = 0;
192+
for (let i = 0; i < n; ++i) {
193+
for (let h = 0; h <= k; ++h) {
194+
for (let j = 0; j < i; ++j) {
195+
if (nums[i] === nums[j]) {
196+
f[i][h] = Math.max(f[i][h], f[j][h]);
197+
} else if (h) {
198+
f[i][h] = Math.max(f[i][h], f[j][h - 1]);
199+
}
200+
}
201+
++f[i][h];
202+
}
203+
ans = Math.max(ans, f[i][k]);
204+
}
205+
return ans;
206+
}
207+
```
208+
209+
<!-- tabs:end -->
210+
211+
<!-- solution:end -->
212+
213+
<!-- solution:start -->
214+
215+
### 方法二:动态规划优化
216+
217+
根据方法一的状态转移方程,如果 $nums[i] = nums[j]$,那么我们只需要获取 $f[j][h]$ 的最大值,我们可以用一个长度为 $k + 1$ 的数组 $mp$ 来维护。如果 $nums[i] \neq nums[j]$,我们需要记录 $f[j][h - 1]$ 的最大值对应的 $nums[j]$,最大值和次大值,我们可以用一个长度为 $k + 1$ 的数组 $g$ 来维护。
218+
219+
时间复杂度 $O(n \times k)$,空间复杂度 $O(n \times k)$。其中 $n$ 是数组 `nums` 的长度。
220+
221+
<!-- tabs:start -->
222+
223+
#### Python3
224+
225+
```python
226+
class Solution:
227+
def maximumLength(self, nums: List[int], k: int) -> int:
228+
n = len(nums)
229+
f = [[0] * (k + 1) for _ in range(n)]
230+
mp = [defaultdict(int) for _ in range(k + 1)]
231+
g = [[0] * 3 for _ in range(k + 1)]
232+
ans = 0
233+
for i, x in enumerate(nums):
234+
for h in range(k + 1):
235+
f[i][h] = mp[h][x]
236+
if h:
237+
if g[h - 1][0] != nums[i]:
238+
f[i][h] = max(f[i][h], g[h - 1][1])
239+
else:
240+
f[i][h] = max(f[i][h], g[h - 1][2])
241+
f[i][h] += 1
242+
mp[h][nums[i]] = max(mp[h][nums[i]], f[i][h])
243+
if g[h][0] != x:
244+
if f[i][h] >= g[h][1]:
245+
g[h][2] = g[h][1]
246+
g[h][1] = f[i][h]
247+
g[h][0] = x
248+
else:
249+
g[h][2] = max(g[h][2], f[i][h])
250+
else:
251+
g[h][1] = max(g[h][1], f[i][h])
252+
ans = max(ans, f[i][h])
253+
return ans
254+
```
255+
256+
#### Java
257+
258+
```java
259+
class Solution {
260+
public int maximumLength(int[] nums, int k) {
261+
int n = nums.length;
262+
int[][] f = new int[n][k + 1];
263+
Map<Integer, Integer>[] mp = new HashMap[k + 1];
264+
Arrays.setAll(mp, i -> new HashMap<>());
265+
int[][] g = new int[k + 1][3];
266+
int ans = 0;
267+
for (int i = 0; i < n; ++i) {
268+
for (int h = 0; h <= k; ++h) {
269+
f[i][h] = mp[h].getOrDefault(nums[i], 0);
270+
if (h > 0) {
271+
if (g[h - 1][0] != nums[i]) {
272+
f[i][h] = Math.max(f[i][h], g[h - 1][1]);
273+
} else {
274+
f[i][h] = Math.max(f[i][h], g[h - 1][2]);
275+
}
276+
}
277+
++f[i][h];
278+
mp[h].merge(nums[i], f[i][h], Integer::max);
279+
if (g[h][0] != nums[i]) {
280+
if (f[i][h] >= g[h][1]) {
281+
g[h][2] = g[h][1];
282+
g[h][1] = f[i][h];
283+
g[h][0] = nums[i];
284+
} else {
285+
g[h][2] = Math.max(g[h][2], f[i][h]);
286+
}
287+
} else {
288+
g[h][1] = Math.max(g[h][1], f[i][h]);
289+
}
290+
ans = Math.max(ans, f[i][h]);
291+
}
292+
}
293+
return ans;
294+
}
295+
}
296+
```
297+
298+
#### C++
86299

300+
```cpp
301+
class Solution {
302+
public:
303+
int maximumLength(vector<int>& nums, int k) {
304+
int n = nums.size();
305+
vector<vector<int>> f(n, vector<int>(k + 1));
306+
vector<unordered_map<int, int>> mp(k + 1);
307+
vector<vector<int>> g(k + 1, vector<int>(3));
308+
int ans = 0;
309+
for (int i = 0; i < n; ++i) {
310+
for (int h = 0; h <= k; ++h) {
311+
f[i][h] = mp[h][nums[i]];
312+
if (h > 0) {
313+
if (g[h - 1][0] != nums[i]) {
314+
f[i][h] = max(f[i][h], g[h - 1][1]);
315+
} else {
316+
f[i][h] = max(f[i][h], g[h - 1][2]);
317+
}
318+
}
319+
++f[i][h];
320+
mp[h][nums[i]] = max(mp[h][nums[i]], f[i][h]);
321+
if (g[h][0] != nums[i]) {
322+
if (f[i][h] >= g[h][1]) {
323+
g[h][2] = g[h][1];
324+
g[h][1] = f[i][h];
325+
g[h][0] = nums[i];
326+
} else {
327+
g[h][2] = max(g[h][2], f[i][h]);
328+
}
329+
} else {
330+
g[h][1] = max(g[h][1], f[i][h]);
331+
}
332+
ans = max(ans, f[i][h]);
333+
}
334+
}
335+
336+
return ans;
337+
}
338+
};
87339
```
88340

89341
#### Go
90342

91343
```go
344+
func maximumLength(nums []int, k int) int {
345+
n := len(nums)
346+
f := make([][]int, n)
347+
for i := range f {
348+
f[i] = make([]int, k+1)
349+
}
350+
mp := make([]map[int]int, k+1)
351+
for i := range mp {
352+
mp[i] = make(map[int]int)
353+
}
354+
g := make([][3]int, k+1)
355+
ans := 0
356+
357+
for i := 0; i < n; i++ {
358+
for h := 0; h <= k; h++ {
359+
f[i][h] = mp[h][nums[i]]
360+
if h > 0 {
361+
if g[h-1][0] != nums[i] {
362+
if g[h-1][1] > f[i][h] {
363+
f[i][h] = g[h-1][1]
364+
}
365+
} else {
366+
if g[h-1][2] > f[i][h] {
367+
f[i][h] = g[h-1][2]
368+
}
369+
}
370+
}
371+
f[i][h]++
372+
if f[i][h] > mp[h][nums[i]] {
373+
mp[h][nums[i]] = f[i][h]
374+
}
375+
if g[h][0] != nums[i] {
376+
if f[i][h] >= g[h][1] {
377+
g[h][2] = g[h][1]
378+
g[h][1] = f[i][h]
379+
g[h][0] = nums[i]
380+
} else if f[i][h] > g[h][2] {
381+
g[h][2] = f[i][h]
382+
}
383+
} else {
384+
if f[i][h] > g[h][1] {
385+
g[h][1] = f[i][h]
386+
}
387+
}
388+
if f[i][h] > ans {
389+
ans = f[i][h]
390+
}
391+
}
392+
}
393+
394+
return ans
395+
}
396+
```
92397

398+
#### TypeScript
399+
400+
```ts
401+
function maximumLength(nums: number[], k: number): number {
402+
const n = nums.length;
403+
const f: number[][] = Array.from({ length: n }, () => Array(k + 1).fill(0));
404+
const mp: Map<number, number>[] = Array.from({ length: k + 1 }, () => new Map());
405+
const g: number[][] = Array.from({ length: k + 1 }, () => Array(3).fill(0));
406+
let ans = 0;
407+
408+
for (let i = 0; i < n; i++) {
409+
for (let h = 0; h <= k; h++) {
410+
f[i][h] = mp[h].get(nums[i]) || 0;
411+
if (h > 0) {
412+
if (g[h - 1][0] !== nums[i]) {
413+
f[i][h] = Math.max(f[i][h], g[h - 1][1]);
414+
} else {
415+
f[i][h] = Math.max(f[i][h], g[h - 1][2]);
416+
}
417+
}
418+
f[i][h]++;
419+
mp[h].set(nums[i], Math.max(mp[h].get(nums[i]) || 0, f[i][h]));
420+
if (g[h][0] !== nums[i]) {
421+
if (f[i][h] >= g[h][1]) {
422+
g[h][2] = g[h][1];
423+
g[h][1] = f[i][h];
424+
g[h][0] = nums[i];
425+
} else {
426+
g[h][2] = Math.max(g[h][2], f[i][h]);
427+
}
428+
} else {
429+
g[h][1] = Math.max(g[h][1], f[i][h]);
430+
}
431+
ans = Math.max(ans, f[i][h]);
432+
}
433+
}
434+
435+
return ans;
436+
}
93437
```
94438

95439
<!-- tabs:end -->

0 commit comments

Comments
 (0)