Skip to content

Commit b25082d

Browse files
committed
feat: add solutions to lc problem: No.1278
No.1278.Palindrome Partitioning III
1 parent 1df504d commit b25082d

File tree

6 files changed

+364
-24
lines changed

6 files changed

+364
-24
lines changed

solution/1200-1299/1278.Palindrome Partitioning III/README.md

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,154 @@
5151

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

54+
**方法一:动态规划**
55+
56+
定义 $dp[i][j]$ 表示将字符串 $s$ 的前 $i$ 个字符分割成 $j$ 个回文串所需要的最少修改次数,我们假定 $i$ 下标从 $1$ 开始,答案为 $dp[n][k]$。
57+
58+
对于 $dp[i][j]$,我们可以枚举第 $j-1$ 个回文串的最后一个字符的位置 $h$,那么 $dp[i][j]$ 就等于 $dp[h][j-1] + g[h][i-1]$ 的较小值,其中 $g[h][i-1]$ 表示将字符串 $s[h..i-1]$ 变成回文串所需要的最少修改次数(这一部分我们可以通过预处理得到,时间复杂度 $O(n^2)$。
59+
60+
时间复杂度 $O(n^2\times k)$。其中 $n$ 为字符串 $s$ 的长度。
61+
5462
<!-- tabs:start -->
5563

5664
### **Python3**
5765

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

6068
```python
61-
69+
class Solution:
70+
def palindromePartition(self, s: str, k: int) -> int:
71+
n = len(s)
72+
g = [[0] * n for _ in range(n)]
73+
for i in range(n - 1, -1, -1):
74+
for j in range(i + 1, n):
75+
g[i][j] = int(s[i] != s[j])
76+
if i + 1 < j:
77+
g[i][j] += g[i + 1][j - 1]
78+
79+
f = [[0] * (k + 1) for _ in range(n + 1)]
80+
for i in range(1, n + 1):
81+
for j in range(1, min(i, k) + 1):
82+
if j == 1:
83+
f[i][j] = g[0][i - 1]
84+
else:
85+
f[i][j] = inf
86+
for h in range(j - 1, i):
87+
f[i][j] = min(f[i][j], f[h][j - 1] + g[h][i - 1])
88+
return f[n][k]
6289
```
6390

6491
### **Java**
6592

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

6895
```java
96+
class Solution {
97+
public int palindromePartition(String s, int k) {
98+
int n = s.length();
99+
int[][] g = new int[n][n];
100+
for (int i = n - 1; i >= 0; --i) {
101+
for (int j = i; j < n; ++j) {
102+
g[i][j] = s.charAt(i) != s.charAt(j) ? 1 : 0;
103+
if (i + 1 < j) {
104+
g[i][j] += g[i + 1][j - 1];
105+
}
106+
}
107+
}
108+
int[][] f = new int[n + 1][k + 1];
109+
for (int i = 1; i <= n; ++i) {
110+
for (int j = 1; j <= Math.min(i, k); ++j) {
111+
if (j == 1) {
112+
f[i][j] = g[0][i - 1];
113+
} else {
114+
f[i][j] = 10000;
115+
for (int h = j - 1; h < i; ++h) {
116+
f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]);
117+
}
118+
}
119+
}
120+
}
121+
return f[n][k];
122+
}
123+
}
124+
```
125+
126+
### **C++**
127+
128+
```cpp
129+
class Solution {
130+
public:
131+
int palindromePartition(string s, int k) {
132+
int n = s.size();
133+
vector<vector<int>> g(n, vector<int>(n));
134+
for (int i = n - 1; i >= 0; --i) {
135+
for (int j = i; j < n; ++j) {
136+
g[i][j] = s[i] != s[j] ? 1 : 0;
137+
if (i + 1 < j) g[i][j] += g[i + 1][j - 1];
138+
}
139+
}
140+
vector<vector<int>> f(n + 1, vector<int>(k + 1));
141+
for (int i = 1; i <= n; ++i) {
142+
for (int j = 1; j <= min(i, k); ++j) {
143+
if (j == 1) {
144+
f[i][j] = g[0][i - 1];
145+
} else {
146+
f[i][j] = 10000;
147+
for (int h = j - 1; h < i; ++h) {
148+
f[i][j] = min(f[i][j], f[h][j - 1] + g[h][i - 1]);
149+
}
150+
}
151+
}
152+
}
153+
return f[n][k];
154+
}
155+
};
156+
```
69157
158+
### **Go**
159+
160+
```go
161+
func palindromePartition(s string, k int) int {
162+
n := len(s)
163+
g := make([][]int, n)
164+
for i := range g {
165+
g[i] = make([]int, n)
166+
}
167+
for i := n - 1; i >= 0; i-- {
168+
for j := 1; j < n; j++ {
169+
if s[i] != s[j] {
170+
g[i][j] = 1
171+
}
172+
if i+1 < j {
173+
g[i][j] += g[i+1][j-1]
174+
}
175+
}
176+
}
177+
f := make([][]int, n+1)
178+
for i := range f {
179+
f[i] = make([]int, k+1)
180+
}
181+
for i := 1; i <= n; i++ {
182+
for j := 1; j <= min(i, k); j++ {
183+
if j == 1 {
184+
f[i][j] = g[0][i-1]
185+
} else {
186+
f[i][j] = 100000
187+
for h := j - 1; h < i; h++ {
188+
f[i][j] = min(f[i][j], f[h][j-1]+g[h][i-1])
189+
}
190+
}
191+
}
192+
}
193+
return f[n][k]
194+
}
195+
196+
func min(a, b int) int {
197+
if a < b {
198+
return a
199+
}
200+
return b
201+
}
70202
```
71203

72204
### **...**

solution/1200-1299/1278.Palindrome Partitioning III/README_EN.md

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,137 @@
5151
### **Python3**
5252

5353
```python
54-
54+
class Solution:
55+
def palindromePartition(self, s: str, k: int) -> int:
56+
n = len(s)
57+
g = [[0] * n for _ in range(n)]
58+
for i in range(n - 1, -1, -1):
59+
for j in range(i + 1, n):
60+
g[i][j] = int(s[i] != s[j])
61+
if i + 1 < j:
62+
g[i][j] += g[i + 1][j - 1]
63+
64+
f = [[0] * (k + 1) for _ in range(n + 1)]
65+
for i in range(1, n + 1):
66+
for j in range(1, min(i, k) + 1):
67+
if j == 1:
68+
f[i][j] = g[0][i - 1]
69+
else:
70+
f[i][j] = inf
71+
for h in range(j - 1, i):
72+
f[i][j] = min(f[i][j], f[h][j - 1] + g[h][i - 1])
73+
return f[n][k]
5574
```
5675

5776
### **Java**
5877

5978
```java
79+
class Solution {
80+
public int palindromePartition(String s, int k) {
81+
int n = s.length();
82+
int[][] g = new int[n][n];
83+
for (int i = n - 1; i >= 0; --i) {
84+
for (int j = i; j < n; ++j) {
85+
g[i][j] = s.charAt(i) != s.charAt(j) ? 1 : 0;
86+
if (i + 1 < j) {
87+
g[i][j] += g[i + 1][j - 1];
88+
}
89+
}
90+
}
91+
int[][] f = new int[n + 1][k + 1];
92+
for (int i = 1; i <= n; ++i) {
93+
for (int j = 1; j <= Math.min(i, k); ++j) {
94+
if (j == 1) {
95+
f[i][j] = g[0][i - 1];
96+
} else {
97+
f[i][j] = 10000;
98+
for (int h = j - 1; h < i; ++h) {
99+
f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]);
100+
}
101+
}
102+
}
103+
}
104+
return f[n][k];
105+
}
106+
}
107+
```
108+
109+
### **C++**
110+
111+
```cpp
112+
class Solution {
113+
public:
114+
int palindromePartition(string s, int k) {
115+
int n = s.size();
116+
vector<vector<int>> g(n, vector<int>(n));
117+
for (int i = n - 1; i >= 0; --i) {
118+
for (int j = i; j < n; ++j) {
119+
g[i][j] = s[i] != s[j] ? 1 : 0;
120+
if (i + 1 < j) g[i][j] += g[i + 1][j - 1];
121+
}
122+
}
123+
vector<vector<int>> f(n + 1, vector<int>(k + 1));
124+
for (int i = 1; i <= n; ++i) {
125+
for (int j = 1; j <= min(i, k); ++j) {
126+
if (j == 1) {
127+
f[i][j] = g[0][i - 1];
128+
} else {
129+
f[i][j] = 10000;
130+
for (int h = j - 1; h < i; ++h) {
131+
f[i][j] = min(f[i][j], f[h][j - 1] + g[h][i - 1]);
132+
}
133+
}
134+
}
135+
}
136+
return f[n][k];
137+
}
138+
};
139+
```
60140
141+
### **Go**
142+
143+
```go
144+
func palindromePartition(s string, k int) int {
145+
n := len(s)
146+
g := make([][]int, n)
147+
for i := range g {
148+
g[i] = make([]int, n)
149+
}
150+
for i := n - 1; i >= 0; i-- {
151+
for j := 1; j < n; j++ {
152+
if s[i] != s[j] {
153+
g[i][j] = 1
154+
}
155+
if i+1 < j {
156+
g[i][j] += g[i+1][j-1]
157+
}
158+
}
159+
}
160+
f := make([][]int, n+1)
161+
for i := range f {
162+
f[i] = make([]int, k+1)
163+
}
164+
for i := 1; i <= n; i++ {
165+
for j := 1; j <= min(i, k); j++ {
166+
if j == 1 {
167+
f[i][j] = g[0][i-1]
168+
} else {
169+
f[i][j] = 100000
170+
for h := j - 1; h < i; h++ {
171+
f[i][j] = min(f[i][j], f[h][j-1]+g[h][i-1])
172+
}
173+
}
174+
}
175+
}
176+
return f[n][k]
177+
}
178+
179+
func min(a, b int) int {
180+
if a < b {
181+
return a
182+
}
183+
return b
184+
}
61185
```
62186

63187
### **...**
Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,27 @@
11
class Solution {
22
public:
33
int palindromePartition(string s, int k) {
4-
int len = s.length();
5-
// cost[i][j] = min #changes needed to turn (s[i],...,s[i+j]) into a palindrome
6-
vector<vector<int>> cost(len, vector<int>(len));
7-
for (int i = 0; i < len; i++) {
8-
for (int j = i; j < len; j++) {
9-
int begin = i, end = j, cnt = 0;
10-
while (begin < end) {
11-
if (s[begin] != s[end])
12-
cnt++;
13-
begin++, end--;
14-
}
15-
cost[i][j - i] = cnt;
4+
int n = s.size();
5+
vector<vector<int>> g(n, vector<int>(n));
6+
for (int i = n - 1; i >= 0; --i) {
7+
for (int j = i; j < n; ++j) {
8+
g[i][j] = s[i] != s[j] ? 1 : 0;
9+
if (i + 1 < j) g[i][j] += g[i + 1][j - 1];
1610
}
1711
}
18-
// dp[i][j] = min #changes needed to split (s[i],...,s[len]) into j+1 palindromes
19-
vector<vector<int>> dp(len, vector<int>(k, INT_MAX));
20-
for (int i = 0; i < len; i++) {
21-
dp[i][0] = cost[i][len - 1 - i];
22-
}
23-
for (int kk = 1; kk < k; kk++) {
24-
for (int i = 0; i < len; i++) {
25-
for (int j = i + 1; j + kk - 1 < len; j++) {
26-
dp[i][kk] = min(dp[i][kk], dp[j][kk - 1] + cost[i][j - i - 1]);
12+
vector<vector<int>> f(n + 1, vector<int>(k + 1));
13+
for (int i = 1; i <= n; ++i) {
14+
for (int j = 1; j <= min(i, k); ++j) {
15+
if (j == 1) {
16+
f[i][j] = g[0][i - 1];
17+
} else {
18+
f[i][j] = 10000;
19+
for (int h = j - 1; h < i; ++h) {
20+
f[i][j] = min(f[i][j], f[h][j - 1] + g[h][i - 1]);
21+
}
2722
}
2823
}
2924
}
30-
return dp[0][k - 1];
25+
return f[n][k];
3126
}
3227
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
func palindromePartition(s string, k int) int {
2+
n := len(s)
3+
g := make([][]int, n)
4+
for i := range g {
5+
g[i] = make([]int, n)
6+
}
7+
for i := n - 1; i >= 0; i-- {
8+
for j := 1; j < n; j++ {
9+
if s[i] != s[j] {
10+
g[i][j] = 1
11+
}
12+
if i+1 < j {
13+
g[i][j] += g[i+1][j-1]
14+
}
15+
}
16+
}
17+
f := make([][]int, n+1)
18+
for i := range f {
19+
f[i] = make([]int, k+1)
20+
}
21+
for i := 1; i <= n; i++ {
22+
for j := 1; j <= min(i, k); j++ {
23+
if j == 1 {
24+
f[i][j] = g[0][i-1]
25+
} else {
26+
f[i][j] = 100000
27+
for h := j - 1; h < i; h++ {
28+
f[i][j] = min(f[i][j], f[h][j-1]+g[h][i-1])
29+
}
30+
}
31+
}
32+
}
33+
return f[n][k]
34+
}
35+
36+
func min(a, b int) int {
37+
if a < b {
38+
return a
39+
}
40+
return b
41+
}

0 commit comments

Comments
 (0)