Skip to content

Commit 37fb2dc

Browse files
committed
feat: add solutions to lc problem: No.1312
No.1312.Minimum Insertion Steps to Make a String Palindrome
1 parent a466920 commit 37fb2dc

File tree

3 files changed

+243
-1
lines changed
  • solution

3 files changed

+243
-1
lines changed

solution/1000-1099/1039.Minimum Score Triangulation of Polygon/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ $$
105105

106106
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为多边形的顶点数。
107107

108+
相似题目:
109+
110+
- [1312. 让字符串成为回文串的最少插入次数](/solution/1300-1399/1312.Minimum%20Insertion%20Steps%20to%20Make%20a%20String%20Palindrome/README.md)
111+
108112
<!-- tabs:start -->
109113

110114
### **Python3**

solution/1300-1399/1312.Minimum Insertion Steps to Make a String Palindrome/README.md

+130-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,23 @@
5151

5252
<!-- 这里可写通用的实现逻辑 -->
5353

54-
**方法一:动态规划(区间 DP)**
54+
**方法一:记忆化搜索**
55+
56+
我们设计一个函数 $dfs(i, j)$,表示将字符串 $s[i..j]$ 变成回文串所需要的最少操作次数。那么答案就是 $dfs(0, n - 1)$。
57+
58+
函数 $dfs(i, j)$ 的计算过程如下:
59+
60+
如果 $i \geq j$,此时无需插入任何字符,我们直接返回 $0$。
61+
62+
否则,我们判断 $s[i]$ 与 $s[j]$ 是否相等,如果 $s[i]=s[j]$,那么我们只需要将 $s[i+1..j-1]$ 变成回文串,那么我们返回 $dfs(i + 1, j - 1)$。否则,我们可以在 $s[i]$ 的左侧或者 $s[j]$ 的右侧插入一个与另一侧相同的字符,那么 $dfs(i, j) = \min(dfs(i + 1, j), dfs(i, j - 1)) + 1$。
63+
64+
为了避免重复计算,我们可以使用记忆化搜索,即使用哈希表或者数组来存储已经计算过的函数值。
65+
66+
最后,我们返回 $dfs(0, n - 1)$ 即可。
67+
68+
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为字符串 $s$ 的长度。
69+
70+
**方法二:动态规划(区间 DP)**
5571

5672
我们定义 $f[i][j]$ 表示将字符串 $s[i..j]$ 变成回文串所需要的最少操作次数。初始时 $f[i][j]=0$,答案即为 $f[0][n-1]$。
5773

@@ -70,12 +86,30 @@ $$
7086

7187
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为字符串 $s$ 的长度。
7288

89+
相似题目:
90+
91+
- [1039. 多边形三角剖分的最低得分](/solution/1000-1099/1039.Minimum%20Score%20Triangulation%20of%20Polygon/README.md)
92+
7393
<!-- tabs:start -->
7494

7595
### **Python3**
7696

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

99+
```python
100+
class Solution:
101+
def minInsertions(self, s: str) -> int:
102+
@cache
103+
def dfs(i: int, j: int) -> int:
104+
if i >= j:
105+
return 0
106+
if s[i] == s[j]:
107+
return dfs(i + 1, j - 1)
108+
return 1 + min(dfs(i + 1, j), dfs(i, j - 1))
109+
110+
return dfs(0, len(s) - 1)
111+
```
112+
79113
```python
80114
class Solution:
81115
def minInsertions(self, s: str) -> int:
@@ -109,6 +143,36 @@ class Solution:
109143

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

146+
```java
147+
class Solution {
148+
private Integer[][] f;
149+
private String s;
150+
151+
public int minInsertions(String s) {
152+
this.s = s;
153+
int n = s.length();
154+
f = new Integer[n][n];
155+
return dfs(0, n - 1);
156+
}
157+
158+
private int dfs(int i, int j) {
159+
if (i >= j) {
160+
return 0;
161+
}
162+
if (f[i][j] != null) {
163+
return f[i][j];
164+
}
165+
int ans = 1 << 30;
166+
if (s.charAt(i) == s.charAt(j)) {
167+
ans = dfs(i + 1, j - 1);
168+
} else {
169+
ans = Math.min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
170+
}
171+
return f[i][j] = ans;
172+
}
173+
}
174+
```
175+
112176
```java
113177
class Solution {
114178
public int minInsertions(String s) {
@@ -150,6 +214,33 @@ class Solution {
150214

151215
### **C++**
152216

217+
```cpp
218+
class Solution {
219+
public:
220+
int minInsertions(string s) {
221+
int n = s.size();
222+
int f[n][n];
223+
memset(f, -1, sizeof(f));
224+
function<int(int, int)> dfs = [&](int i, int j) -> int {
225+
if (i >= j) {
226+
return 0;
227+
}
228+
if (f[i][j] != -1) {
229+
return f[i][j];
230+
}
231+
int ans = 1 << 30;
232+
if (s[i] == s[j]) {
233+
ans = dfs(i + 1, j - 1);
234+
} else {
235+
ans = min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
236+
}
237+
return f[i][j] = ans;
238+
};
239+
return dfs(0, n - 1);
240+
}
241+
};
242+
```
243+
153244
```cpp
154245
class Solution {
155246
public:
@@ -195,6 +286,44 @@ public:
195286
196287
### **Go**
197288
289+
```go
290+
func minInsertions(s string) int {
291+
n := len(s)
292+
f := make([][]int, n)
293+
for i := range f {
294+
f[i] = make([]int, n)
295+
for j := range f[i] {
296+
f[i][j] = -1
297+
}
298+
}
299+
var dfs func(i, j int) int
300+
dfs = func(i, j int) int {
301+
if i >= j {
302+
return 0
303+
}
304+
if f[i][j] != -1 {
305+
return f[i][j]
306+
}
307+
ans := 1 << 30
308+
if s[i] == s[j] {
309+
ans = dfs(i+1, j-1)
310+
} else {
311+
ans = min(dfs(i+1, j), dfs(i, j-1)) + 1
312+
}
313+
f[i][j] = ans
314+
return ans
315+
}
316+
return dfs(0, n-1)
317+
}
318+
319+
func min(a, b int) int {
320+
if a < b {
321+
return a
322+
}
323+
return b
324+
}
325+
```
326+
198327
```go
199328
func minInsertions(s string) int {
200329
n := len(s)

solution/1300-1399/1312.Minimum Insertion Steps to Make a String Palindrome/README_EN.md

+109
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@
4949

5050
### **Python3**
5151

52+
```python
53+
class Solution:
54+
def minInsertions(self, s: str) -> int:
55+
@cache
56+
def dfs(i: int, j: int) -> int:
57+
if i >= j:
58+
return 0
59+
if s[i] == s[j]:
60+
return dfs(i + 1, j - 1)
61+
return 1 + min(dfs(i + 1, j), dfs(i, j - 1))
62+
63+
return dfs(0, len(s) - 1)
64+
```
65+
5266
```python
5367
class Solution:
5468
def minInsertions(self, s: str) -> int:
@@ -80,6 +94,36 @@ class Solution:
8094

8195
### **Java**
8296

97+
```java
98+
class Solution {
99+
private Integer[][] f;
100+
private String s;
101+
102+
public int minInsertions(String s) {
103+
this.s = s;
104+
int n = s.length();
105+
f = new Integer[n][n];
106+
return dfs(0, n - 1);
107+
}
108+
109+
private int dfs(int i, int j) {
110+
if (i >= j) {
111+
return 0;
112+
}
113+
if (f[i][j] != null) {
114+
return f[i][j];
115+
}
116+
int ans = 1 << 30;
117+
if (s.charAt(i) == s.charAt(j)) {
118+
ans = dfs(i + 1, j - 1);
119+
} else {
120+
ans = Math.min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
121+
}
122+
return f[i][j] = ans;
123+
}
124+
}
125+
```
126+
83127
```java
84128
class Solution {
85129
public int minInsertions(String s) {
@@ -121,6 +165,33 @@ class Solution {
121165

122166
### **C++**
123167

168+
```cpp
169+
class Solution {
170+
public:
171+
int minInsertions(string s) {
172+
int n = s.size();
173+
int f[n][n];
174+
memset(f, -1, sizeof(f));
175+
function<int(int, int)> dfs = [&](int i, int j) -> int {
176+
if (i >= j) {
177+
return 0;
178+
}
179+
if (f[i][j] != -1) {
180+
return f[i][j];
181+
}
182+
int ans = 1 << 30;
183+
if (s[i] == s[j]) {
184+
ans = dfs(i + 1, j - 1);
185+
} else {
186+
ans = min(dfs(i + 1, j), dfs(i, j - 1)) + 1;
187+
}
188+
return f[i][j] = ans;
189+
};
190+
return dfs(0, n - 1);
191+
}
192+
};
193+
```
194+
124195
```cpp
125196
class Solution {
126197
public:
@@ -166,6 +237,44 @@ public:
166237
167238
### **Go**
168239
240+
```go
241+
func minInsertions(s string) int {
242+
n := len(s)
243+
f := make([][]int, n)
244+
for i := range f {
245+
f[i] = make([]int, n)
246+
for j := range f[i] {
247+
f[i][j] = -1
248+
}
249+
}
250+
var dfs func(i, j int) int
251+
dfs = func(i, j int) int {
252+
if i >= j {
253+
return 0
254+
}
255+
if f[i][j] != -1 {
256+
return f[i][j]
257+
}
258+
ans := 1 << 30
259+
if s[i] == s[j] {
260+
ans = dfs(i+1, j-1)
261+
} else {
262+
ans = min(dfs(i+1, j), dfs(i, j-1)) + 1
263+
}
264+
f[i][j] = ans
265+
return ans
266+
}
267+
return dfs(0, n-1)
268+
}
269+
270+
func min(a, b int) int {
271+
if a < b {
272+
return a
273+
}
274+
return b
275+
}
276+
```
277+
169278
```go
170279
func minInsertions(s string) int {
171280
n := len(s)

0 commit comments

Comments
 (0)