Skip to content

Commit e8ccff4

Browse files
authored
feat: add solutions to lc problem: No.1278 (#4122)
No.1278.Palindrome Partitioning III
1 parent caccf24 commit e8ccff4

File tree

4 files changed

+210
-4
lines changed

4 files changed

+210
-4
lines changed

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

+73-3
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ tags:
6868

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

71-
定义 $dp[i][j]$ 表示将字符串 $s$ 的前 $i$ 个字符分割成 $j$ 个回文串所需要的最少修改次数,我们假定 $i$ 下标从 $1$ 开始,答案为 $dp[n][k]$。
71+
我们定义 $f[i][j]$ 表示将字符串 $s$ 的前 $i$ 个字符分割成 $j$ 个回文串所需要的最少修改次数,我们假定 $i$ 下标从 $1$ 开始,答案为 $f[n][k]$。
7272

73-
对于 $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)$。
73+
对于 $f[i][j]$,我们可以枚举第 $j-1$ 个回文串的最后一个字符的位置 $h$,那么 $f[i][j]$ 就等于 $f[h][j-1] + g[h][i-1]$ 的较小值,其中 $g[h][i-1]$ 表示将字符串 $s[h..i-1]$ 变成回文串所需要的最少修改次数(这一部分我们可以通过预处理得到,时间复杂度 $O(n^2)$。
7474

75-
时间复杂度 $O(n^2\times k)$。其中 $n$ 为字符串 $s$ 的长度。
75+
时间复杂度 $O(n^2 \times k)$,空间复杂度 $O(n \times (n + k))$。其中 $n$ 为字符串 $s$ 的长度。
7676

7777
<!-- tabs:start -->
7878

@@ -205,6 +205,76 @@ func palindromePartition(s string, k int) int {
205205
}
206206
```
207207

208+
#### TypeScript
209+
210+
```ts
211+
function palindromePartition(s: string, k: number): number {
212+
const n = s.length;
213+
const g: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
214+
for (let i = n - 1; i >= 0; i--) {
215+
for (let j = i + 1; j < n; j++) {
216+
g[i][j] = s[i] !== s[j] ? 1 : 0;
217+
if (i + 1 < j) {
218+
g[i][j] += g[i + 1][j - 1];
219+
}
220+
}
221+
}
222+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0));
223+
for (let i = 1; i <= n; i++) {
224+
for (let j = 1; j <= Math.min(i, k); j++) {
225+
if (j === 1) {
226+
f[i][j] = g[0][i - 1];
227+
} else {
228+
f[i][j] = 1 << 30;
229+
for (let h = j - 1; h < i; h++) {
230+
f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]);
231+
}
232+
}
233+
}
234+
}
235+
return f[n][k];
236+
}
237+
```
238+
239+
#### Rust
240+
241+
```rust
242+
impl Solution {
243+
pub fn palindrome_partition(s: String, k: i32) -> i32 {
244+
let n = s.len();
245+
let s: Vec<char> = s.chars().collect();
246+
let mut g = vec![vec![0; n]; n];
247+
248+
for i in (0..n).rev() {
249+
for j in i + 1..n {
250+
g[i][j] = if s[i] != s[j] { 1 } else { 0 };
251+
if i + 1 < j {
252+
g[i][j] += g[i + 1][j - 1];
253+
}
254+
}
255+
}
256+
257+
let mut f = vec![vec![0; (k + 1) as usize]; n + 1];
258+
let inf = i32::MAX;
259+
260+
for i in 1..=n {
261+
for j in 1..=i.min(k as usize) {
262+
if j == 1 {
263+
f[i][j] = g[0][i - 1];
264+
} else {
265+
f[i][j] = inf;
266+
for h in (j - 1)..i {
267+
f[i][j] = f[i][j].min(f[h][j - 1] + g[h][i - 1]);
268+
}
269+
}
270+
}
271+
}
272+
273+
f[n][k as usize]
274+
}
275+
}
276+
```
277+
208278
<!-- tabs:end -->
209279

210280
<!-- solution:end -->

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

+77-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ tags:
6565

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

68-
### Solution 1
68+
### Solution 1: Dynamic Programming
69+
70+
We define $f[i][j]$ to represent the minimum number of changes needed to partition the first $i$ characters of the string $s$ into $j$ palindromic substrings. We assume the index $i$ starts from 1, and the answer is $f[n][k]$.
71+
72+
For $f[i][j]$, we can enumerate the position $h$ of the last character of the $(j-1)$-th palindromic substring. Then $f[i][j]$ is equal to the minimum value of $f[h][j-1] + g[h][i-1]$, where $g[h][i-1]$ represents the minimum number of changes needed to turn the substring $s[h..i-1]$ into a palindrome (this part can be preprocessed with a time complexity of $O(n^2)$).
73+
74+
The time complexity is $O(n^2 \times k)$, and the space complexity is $O(n \times (n + k))$. Where $n$ is the length of the string $s$.
6975

7076
<!-- tabs:start -->
7177

@@ -198,6 +204,76 @@ func palindromePartition(s string, k int) int {
198204
}
199205
```
200206

207+
#### TypeScript
208+
209+
```ts
210+
function palindromePartition(s: string, k: number): number {
211+
const n = s.length;
212+
const g: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
213+
for (let i = n - 1; i >= 0; i--) {
214+
for (let j = i + 1; j < n; j++) {
215+
g[i][j] = s[i] !== s[j] ? 1 : 0;
216+
if (i + 1 < j) {
217+
g[i][j] += g[i + 1][j - 1];
218+
}
219+
}
220+
}
221+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0));
222+
for (let i = 1; i <= n; i++) {
223+
for (let j = 1; j <= Math.min(i, k); j++) {
224+
if (j === 1) {
225+
f[i][j] = g[0][i - 1];
226+
} else {
227+
f[i][j] = 1 << 30;
228+
for (let h = j - 1; h < i; h++) {
229+
f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]);
230+
}
231+
}
232+
}
233+
}
234+
return f[n][k];
235+
}
236+
```
237+
238+
#### Rust
239+
240+
```rust
241+
impl Solution {
242+
pub fn palindrome_partition(s: String, k: i32) -> i32 {
243+
let n = s.len();
244+
let s: Vec<char> = s.chars().collect();
245+
let mut g = vec![vec![0; n]; n];
246+
247+
for i in (0..n).rev() {
248+
for j in i + 1..n {
249+
g[i][j] = if s[i] != s[j] { 1 } else { 0 };
250+
if i + 1 < j {
251+
g[i][j] += g[i + 1][j - 1];
252+
}
253+
}
254+
}
255+
256+
let mut f = vec![vec![0; (k + 1) as usize]; n + 1];
257+
let inf = i32::MAX;
258+
259+
for i in 1..=n {
260+
for j in 1..=i.min(k as usize) {
261+
if j == 1 {
262+
f[i][j] = g[0][i - 1];
263+
} else {
264+
f[i][j] = inf;
265+
for h in (j - 1)..i {
266+
f[i][j] = f[i][j].min(f[h][j - 1] + g[h][i - 1]);
267+
}
268+
}
269+
}
270+
}
271+
272+
f[n][k as usize]
273+
}
274+
}
275+
```
276+
201277
<!-- tabs:end -->
202278

203279
<!-- solution:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
impl Solution {
2+
pub fn palindrome_partition(s: String, k: i32) -> i32 {
3+
let n = s.len();
4+
let s: Vec<char> = s.chars().collect();
5+
let mut g = vec![vec![0; n]; n];
6+
7+
for i in (0..n).rev() {
8+
for j in i + 1..n {
9+
g[i][j] = if s[i] != s[j] { 1 } else { 0 };
10+
if i + 1 < j {
11+
g[i][j] += g[i + 1][j - 1];
12+
}
13+
}
14+
}
15+
16+
let mut f = vec![vec![0; (k + 1) as usize]; n + 1];
17+
let inf = i32::MAX;
18+
19+
for i in 1..=n {
20+
for j in 1..=i.min(k as usize) {
21+
if j == 1 {
22+
f[i][j] = g[0][i - 1];
23+
} else {
24+
f[i][j] = inf;
25+
for h in (j - 1)..i {
26+
f[i][j] = f[i][j].min(f[h][j - 1] + g[h][i - 1]);
27+
}
28+
}
29+
}
30+
}
31+
32+
f[n][k as usize]
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function palindromePartition(s: string, k: number): number {
2+
const n = s.length;
3+
const g: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
4+
for (let i = n - 1; i >= 0; i--) {
5+
for (let j = i + 1; j < n; j++) {
6+
g[i][j] = s[i] !== s[j] ? 1 : 0;
7+
if (i + 1 < j) {
8+
g[i][j] += g[i + 1][j - 1];
9+
}
10+
}
11+
}
12+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0));
13+
for (let i = 1; i <= n; i++) {
14+
for (let j = 1; j <= Math.min(i, k); j++) {
15+
if (j === 1) {
16+
f[i][j] = g[0][i - 1];
17+
} else {
18+
f[i][j] = 1 << 30;
19+
for (let h = j - 1; h < i; h++) {
20+
f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]);
21+
}
22+
}
23+
}
24+
}
25+
return f[n][k];
26+
}

0 commit comments

Comments
 (0)