Skip to content

Commit 2cfd23b

Browse files
authored
feat: add solutions to lcp problem: No.19 (#1346)
LCP 19. 秋叶收藏集
1 parent 3dac3f3 commit 2cfd23b

File tree

6 files changed

+256
-1
lines changed

6 files changed

+256
-1
lines changed

lcp/LCP 19. 秋叶收藏集/README.md

+145-1
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,166 @@
4242

4343
<!-- 这里可写通用的实现逻辑 -->
4444

45+
**方法一:动态规划**
46+
47+
我们定义 $f[i][j]$ 表示对于第 $i$ 片叶子,处于状态 $j$ 时的最小操作次数,其中 $j$ 表示:
48+
49+
- 状态 $0$ 表示第 $i$ 片叶子处于左边的红色部分;
50+
- 状态 $1$ 表示第 $i$ 片叶子处于中间的黄色部分;
51+
- 状态 $2$ 表示第 $i$ 片叶子处于右边的红色部分。
52+
53+
初始时,如果第 $0$ 片叶子为红色,那么 $f[0][0] = 0$,如果第 $0$ 片叶子为黄色,那么 $f[0][0] = 1$。对于其余的状态,我们初始化为 $+\infty$,表示在这种状态下无法完成任务。
54+
55+
考虑 $f[i][j]$,其中 $i \ge 1$:
56+
57+
如果第 $i$ 片叶子为红色,那么 $f[i][0]$ 只能从 $f[i-1][0]$ 转移而来,而 $f[i][1]$ 可以从 $f[i-1][0]$ 和 $f[i-1][1]$ 转移而来,此时需要额外操作一次,而 $f[i][2]$ 可以从 $f[i-1][1]$ 和 $f[i-1][2]$ 转移而来,此时不需要额外操作一次。
58+
59+
如果第 $i$ 片叶子为黄色,那么 $f[i][0]$ 只能从 $f[i-1][0]$ 转移而来,并且需要额外操作一次,而 $f[i][1]$ 可以从 $f[i-1][0]$ 和 $f[i-1][1]$ 转移而来,此时不需要额外操作一次,而 $f[i][2]$ 可以从 $f[i-1][1]$ 和 $f[i-1][2]$ 转移而来,并且需要额外操作一次。
60+
61+
最终的答案即为 $f[n-1][2]$,其中 $n$ 表示红叶和黄叶的总数。
62+
63+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
64+
4565
<!-- tabs:start -->
4666

4767
### **Python3**
4868

4969
<!-- 这里可写当前语言的特殊实现逻辑 -->
5070

5171
```python
52-
72+
class Solution:
73+
def minimumOperations(self, leaves: str) -> int:
74+
n = len(leaves)
75+
f = [[inf] * 3 for _ in range(n)]
76+
f[0][0] = int(leaves[0] == "y")
77+
for i in range(1, n):
78+
if leaves[i] == "r":
79+
f[i][0] = f[i - 1][0]
80+
f[i][1] = min(f[i - 1][0], f[i - 1][1]) + 1
81+
f[i][2] = min(f[i - 1][2], f[i - 1][1])
82+
else:
83+
f[i][0] = f[i - 1][0] + 1
84+
f[i][1] = min(f[i - 1][0], f[i - 1][1])
85+
f[i][2] = min(f[i - 1][2], f[i - 1][1]) + 1
86+
return f[n - 1][2]
5387
```
5488

5589
### **Java**
5690

5791
<!-- 这里可写当前语言的特殊实现逻辑 -->
5892

5993
```java
94+
class Solution {
95+
public int minimumOperations(String leaves) {
96+
int n = leaves.length();
97+
final int inf = 1 << 30;
98+
var f = new int[n][3];
99+
for (var g : f) {
100+
Arrays.fill(g, inf);
101+
}
102+
f[0][0] = leaves.charAt(0) == 'r' ? 0 : 1;
103+
for (int i = 1; i < n; ++i) {
104+
if (leaves.charAt(i) == 'r') {
105+
f[i][0] = f[i - 1][0];
106+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]) + 1;
107+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]);
108+
} else {
109+
f[i][0] = f[i - 1][0] + 1;
110+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]);
111+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]) + 1;
112+
}
113+
}
114+
return f[n - 1][2];
115+
}
116+
}
117+
```
118+
119+
### **C++**
120+
121+
```cpp
122+
class Solution {
123+
public:
124+
int minimumOperations(string leaves) {
125+
int n = leaves.size();
126+
int f[n][3];
127+
memset(f, 0x3f, sizeof(f));
128+
f[0][0] = leaves[0] == 'y';
129+
for (int i = 1; i < n; ++i) {
130+
if (leaves[i] == 'r') {
131+
f[i][0] = f[i - 1][0];
132+
f[i][1] = min(f[i - 1][0], f[i - 1][1]) + 1;
133+
f[i][2] = min(f[i - 1][2], f[i - 1][1]);
134+
} else {
135+
f[i][0] = f[i - 1][0] + 1;
136+
f[i][1] = min(f[i - 1][0], f[i - 1][1]);
137+
f[i][2] = min(f[i - 1][2], f[i - 1][1]) + 1;
138+
}
139+
}
140+
return f[n - 1][2];
141+
}
142+
};
143+
```
144+
145+
### **Go**
146+
147+
```go
148+
func minimumOperations(leaves string) int {
149+
n := len(leaves)
150+
f := make([][3]int, n)
151+
inf := 1 << 30
152+
for i := range f {
153+
f[i] = [3]int{inf, inf, inf}
154+
}
155+
if leaves[0] == 'y' {
156+
f[0][0] = 1
157+
} else {
158+
f[0][0] = 0
159+
}
160+
for i := 1; i < n; i++ {
161+
if leaves[i] == 'r' {
162+
f[i][0] = f[i-1][0]
163+
f[i][1] = min(f[i-1][0], f[i-1][1]) + 1
164+
f[i][2] = min(f[i-1][2], f[i-1][1])
165+
} else {
166+
f[i][0] = f[i-1][0] + 1
167+
f[i][1] = min(f[i-1][0], f[i-1][1])
168+
f[i][2] = min(f[i-1][2], f[i-1][1]) + 1
169+
}
170+
}
171+
return f[n-1][2]
172+
}
173+
174+
func min(a, b int) int {
175+
if a < b {
176+
return a
177+
}
178+
return b
179+
}
180+
```
60181

182+
### **TypeScript**
183+
184+
```ts
185+
function minimumOperations(leaves: string): number {
186+
const n = leaves.length;
187+
const inf = 1 << 30;
188+
const f: number[][] = new Array(n)
189+
.fill(0)
190+
.map(() => new Array(3).fill(inf));
191+
f[0][0] = leaves[0] === 'y' ? 1 : 0;
192+
for (let i = 1; i < n; ++i) {
193+
if (leaves[i] === 'r') {
194+
f[i][0] = f[i - 1][0];
195+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]) + 1;
196+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]);
197+
} else {
198+
f[i][0] = f[i - 1][0] + 1;
199+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]);
200+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]) + 1;
201+
}
202+
}
203+
return f[n - 1][2];
204+
}
61205
```
62206

63207
### **...**
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public:
3+
int minimumOperations(string leaves) {
4+
int n = leaves.size();
5+
int f[n][3];
6+
memset(f, 0x3f, sizeof(f));
7+
f[0][0] = leaves[0] == 'y';
8+
for (int i = 1; i < n; ++i) {
9+
if (leaves[i] == 'r') {
10+
f[i][0] = f[i - 1][0];
11+
f[i][1] = min(f[i - 1][0], f[i - 1][1]) + 1;
12+
f[i][2] = min(f[i - 1][2], f[i - 1][1]);
13+
} else {
14+
f[i][0] = f[i - 1][0] + 1;
15+
f[i][1] = min(f[i - 1][0], f[i - 1][1]);
16+
f[i][2] = min(f[i - 1][2], f[i - 1][1]) + 1;
17+
}
18+
}
19+
return f[n - 1][2];
20+
}
21+
};
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
func minimumOperations(leaves string) int {
2+
n := len(leaves)
3+
f := make([][3]int, n)
4+
inf := 1 << 30
5+
for i := range f {
6+
f[i] = [3]int{inf, inf, inf}
7+
}
8+
if leaves[0] == 'y' {
9+
f[0][0] = 1
10+
} else {
11+
f[0][0] = 0
12+
}
13+
for i := 1; i < n; i++ {
14+
if leaves[i] == 'r' {
15+
f[i][0] = f[i-1][0]
16+
f[i][1] = min(f[i-1][0], f[i-1][1]) + 1
17+
f[i][2] = min(f[i-1][2], f[i-1][1])
18+
} else {
19+
f[i][0] = f[i-1][0] + 1
20+
f[i][1] = min(f[i-1][0], f[i-1][1])
21+
f[i][2] = min(f[i-1][2], f[i-1][1]) + 1
22+
}
23+
}
24+
return f[n-1][2]
25+
}
26+
27+
func min(a, b int) int {
28+
if a < b {
29+
return a
30+
}
31+
return b
32+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution {
2+
public int minimumOperations(String leaves) {
3+
int n = leaves.length();
4+
final int inf = 1 << 30;
5+
var f = new int[n][3];
6+
for (var g : f) {
7+
Arrays.fill(g, inf);
8+
}
9+
f[0][0] = leaves.charAt(0) == 'r' ? 0 : 1;
10+
for (int i = 1; i < n; ++i) {
11+
if (leaves.charAt(i) == 'r') {
12+
f[i][0] = f[i - 1][0];
13+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]) + 1;
14+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]);
15+
} else {
16+
f[i][0] = f[i - 1][0] + 1;
17+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]);
18+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]) + 1;
19+
}
20+
}
21+
return f[n - 1][2];
22+
}
23+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution:
2+
def minimumOperations(self, leaves: str) -> int:
3+
n = len(leaves)
4+
f = [[inf] * 3 for _ in range(n)]
5+
f[0][0] = int(leaves[0] == "y")
6+
for i in range(1, n):
7+
if leaves[i] == "r":
8+
f[i][0] = f[i - 1][0]
9+
f[i][1] = min(f[i - 1][0], f[i - 1][1]) + 1
10+
f[i][2] = min(f[i - 1][2], f[i - 1][1])
11+
else:
12+
f[i][0] = f[i - 1][0] + 1
13+
f[i][1] = min(f[i - 1][0], f[i - 1][1])
14+
f[i][2] = min(f[i - 1][2], f[i - 1][1]) + 1
15+
return f[n - 1][2]
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function minimumOperations(leaves: string): number {
2+
const n = leaves.length;
3+
const inf = 1 << 30;
4+
const f: number[][] = new Array(n)
5+
.fill(0)
6+
.map(() => new Array(3).fill(inf));
7+
f[0][0] = leaves[0] === 'y' ? 1 : 0;
8+
for (let i = 1; i < n; ++i) {
9+
if (leaves[i] === 'r') {
10+
f[i][0] = f[i - 1][0];
11+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]) + 1;
12+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]);
13+
} else {
14+
f[i][0] = f[i - 1][0] + 1;
15+
f[i][1] = Math.min(f[i - 1][0], f[i - 1][1]);
16+
f[i][2] = Math.min(f[i - 1][2], f[i - 1][1]) + 1;
17+
}
18+
}
19+
return f[n - 1][2];
20+
}

0 commit comments

Comments
 (0)