Skip to content

Commit a5659f9

Browse files
committed
feat: add solutions to lc problem: No.1216
No.1216.Valid Palindrome III
1 parent 350027c commit a5659f9

File tree

8 files changed

+309
-2
lines changed

8 files changed

+309
-2
lines changed

solution/1200-1299/1216.Valid Palindrome III/README.md

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,133 @@
4141

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

44+
**方法一:动态规划**
45+
46+
题目要求删去最多 $k$ 个字符,使得剩余的字符串是回文串。可以转换为求最长回文子序列的问题。
47+
48+
我们定义 $f[i][j]$ 表示字符串 $s$ 中下标范围 $[i, j]$ 内的最长回文子序列的长度。初始时 $f[i][i] = 1$,即每个单独的字符都是一个回文子序列。
49+
50+
当 $s[i] = s[j]$ 时,有 $f[i][j] = f[i + 1][j - 1] + 2$,即去掉 $s[i]$ 和 $s[j]$ 后,剩余的字符串的最长回文子序列长度加 $2$。
51+
52+
当 $s[i] \neq s[j]$ 时,有 $f[i][j] = \max(f[i + 1][j], f[i][j - 1])$,即去掉 $s[i]$ 或 $s[j]$ 后,剩余的字符串的最长回文子序列长度。
53+
54+
然后是否存在 $f[i][j] + k \geq n$,如果存在,说明可以通过删去 $k$ 个字符,使得剩余的字符串是回文串。
55+
56+
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为字符串 $s$ 的长度。
57+
4458
<!-- tabs:start -->
4559

4660
### **Python3**
4761

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

5064
```python
51-
65+
class Solution:
66+
def isValidPalindrome(self, s: str, k: int) -> bool:
67+
n = len(s)
68+
f = [[0] * n for _ in range(n)]
69+
for i in range(n):
70+
f[i][i] = 1
71+
for i in range(n - 2, -1, -1):
72+
for j in range(i + 1, n):
73+
if s[i] == s[j]:
74+
f[i][j] = f[i + 1][j - 1] + 2
75+
else:
76+
f[i][j] = max(f[i + 1][j], f[i][j - 1])
77+
if f[i][j] + k >= n:
78+
return True
79+
return False
5280
```
5381

5482
### **Java**
5583

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

5886
```java
87+
class Solution {
88+
public boolean isValidPalindrome(String s, int k) {
89+
int n = s.length();
90+
int[][] f = new int[n][n];
91+
for (int i = 0; i < n; ++i) {
92+
f[i][i] = 1;
93+
}
94+
for (int i = n - 2; i >= 0; --i) {
95+
for (int j = i + 1; j < n; ++j) {
96+
if (s.charAt(i) == s.charAt(j)) {
97+
f[i][j] = f[i + 1][j - 1] + 2;
98+
} else {
99+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
100+
}
101+
if (f[i][j] + k >= n) {
102+
return true;
103+
}
104+
}
105+
}
106+
return false;
107+
}
108+
}
109+
```
110+
111+
### **C++**
112+
113+
```cpp
114+
class Solution {
115+
public:
116+
bool isValidPalindrome(string s, int k) {
117+
int n = s.length();
118+
int f[n][n];
119+
memset(f, 0, sizeof f);
120+
for (int i = 0; i < n; ++i) {
121+
f[i][i] = 1;
122+
}
123+
for (int i = n - 2; i >= 0; --i) {
124+
for (int j = i + 1; j < n; ++j) {
125+
if (s[i] == s[j]) {
126+
f[i][j] = f[i + 1][j - 1] + 2;
127+
} else {
128+
f[i][j] = max(f[i + 1][j], f[i][j - 1]);
129+
}
130+
if (f[i][j] + k >= n) {
131+
return true;
132+
}
133+
}
134+
}
135+
return false;
136+
}
137+
};
138+
```
59139
140+
### **Go**
141+
142+
```go
143+
func isValidPalindrome(s string, k int) bool {
144+
n := len(s)
145+
f := make([][]int, n)
146+
for i := range f {
147+
f[i] = make([]int, n)
148+
f[i][i] = 1
149+
}
150+
for i := n - 2; i >= 0; i-- {
151+
for j := i + 1; j < n; j++ {
152+
if s[i] == s[j] {
153+
f[i][j] = f[i+1][j-1] + 2
154+
} else {
155+
f[i][j] = max(f[i+1][j], f[i][j-1])
156+
}
157+
if f[i][j]+k >= n {
158+
return true
159+
}
160+
}
161+
}
162+
return false
163+
}
164+
165+
func max(a, b int) int {
166+
if a > b {
167+
return a
168+
}
169+
return b
170+
}
60171
```
61172

62173
### **...**

solution/1200-1299/1216.Valid Palindrome III/README_EN.md

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,110 @@
4040
### **Python3**
4141

4242
```python
43-
43+
class Solution:
44+
def isValidPalindrome(self, s: str, k: int) -> bool:
45+
n = len(s)
46+
f = [[0] * n for _ in range(n)]
47+
for i in range(n):
48+
f[i][i] = 1
49+
for i in range(n - 2, -1, -1):
50+
for j in range(i + 1, n):
51+
if s[i] == s[j]:
52+
f[i][j] = f[i + 1][j - 1] + 2
53+
else:
54+
f[i][j] = max(f[i + 1][j], f[i][j - 1])
55+
if f[i][j] + k >= n:
56+
return True
57+
return False
4458
```
4559

4660
### **Java**
4761

4862
```java
63+
class Solution {
64+
public boolean isValidPalindrome(String s, int k) {
65+
int n = s.length();
66+
int[][] f = new int[n][n];
67+
for (int i = 0; i < n; ++i) {
68+
f[i][i] = 1;
69+
}
70+
for (int i = n - 2; i >= 0; --i) {
71+
for (int j = i + 1; j < n; ++j) {
72+
if (s.charAt(i) == s.charAt(j)) {
73+
f[i][j] = f[i + 1][j - 1] + 2;
74+
} else {
75+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
76+
}
77+
if (f[i][j] + k >= n) {
78+
return true;
79+
}
80+
}
81+
}
82+
return false;
83+
}
84+
}
85+
```
86+
87+
### **C++**
88+
89+
```cpp
90+
class Solution {
91+
public:
92+
bool isValidPalindrome(string s, int k) {
93+
int n = s.length();
94+
int f[n][n];
95+
memset(f, 0, sizeof f);
96+
for (int i = 0; i < n; ++i) {
97+
f[i][i] = 1;
98+
}
99+
for (int i = n - 2; i >= 0; --i) {
100+
for (int j = i + 1; j < n; ++j) {
101+
if (s[i] == s[j]) {
102+
f[i][j] = f[i + 1][j - 1] + 2;
103+
} else {
104+
f[i][j] = max(f[i + 1][j], f[i][j - 1]);
105+
}
106+
if (f[i][j] + k >= n) {
107+
return true;
108+
}
109+
}
110+
}
111+
return false;
112+
}
113+
};
114+
```
49115
116+
### **Go**
117+
118+
```go
119+
func isValidPalindrome(s string, k int) bool {
120+
n := len(s)
121+
f := make([][]int, n)
122+
for i := range f {
123+
f[i] = make([]int, n)
124+
f[i][i] = 1
125+
}
126+
for i := n - 2; i >= 0; i-- {
127+
for j := i + 1; j < n; j++ {
128+
if s[i] == s[j] {
129+
f[i][j] = f[i+1][j-1] + 2
130+
} else {
131+
f[i][j] = max(f[i+1][j], f[i][j-1])
132+
}
133+
if f[i][j]+k >= n {
134+
return true
135+
}
136+
}
137+
}
138+
return false
139+
}
140+
141+
func max(a, b int) int {
142+
if a > b {
143+
return a
144+
}
145+
return b
146+
}
50147
```
51148

52149
### **...**
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
bool isValidPalindrome(string s, int k) {
4+
int n = s.length();
5+
int f[n][n];
6+
memset(f, 0, sizeof f);
7+
for (int i = 0; i < n; ++i) {
8+
f[i][i] = 1;
9+
}
10+
for (int i = n - 2; i >= 0; --i) {
11+
for (int j = i + 1; j < n; ++j) {
12+
if (s[i] == s[j]) {
13+
f[i][j] = f[i + 1][j - 1] + 2;
14+
} else {
15+
f[i][j] = max(f[i + 1][j], f[i][j - 1]);
16+
}
17+
if (f[i][j] + k >= n) {
18+
return true;
19+
}
20+
}
21+
}
22+
return false;
23+
}
24+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
func isValidPalindrome(s string, k int) bool {
2+
n := len(s)
3+
f := make([][]int, n)
4+
for i := range f {
5+
f[i] = make([]int, n)
6+
f[i][i] = 1
7+
}
8+
for i := n - 2; i >= 0; i-- {
9+
for j := i + 1; j < n; j++ {
10+
if s[i] == s[j] {
11+
f[i][j] = f[i+1][j-1] + 2
12+
} else {
13+
f[i][j] = max(f[i+1][j], f[i][j-1])
14+
}
15+
if f[i][j]+k >= n {
16+
return true
17+
}
18+
}
19+
}
20+
return false
21+
}
22+
23+
func max(a, b int) int {
24+
if a > b {
25+
return a
26+
}
27+
return b
28+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public boolean isValidPalindrome(String s, int k) {
3+
int n = s.length();
4+
int[][] f = new int[n][n];
5+
for (int i = 0; i < n; ++i) {
6+
f[i][i] = 1;
7+
}
8+
for (int i = n - 2; i >= 0; --i) {
9+
for (int j = i + 1; j < n; ++j) {
10+
if (s.charAt(i) == s.charAt(j)) {
11+
f[i][j] = f[i + 1][j - 1] + 2;
12+
} else {
13+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
14+
}
15+
if (f[i][j] + k >= n) {
16+
return true;
17+
}
18+
}
19+
}
20+
return false;
21+
}
22+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution:
2+
def isValidPalindrome(self, s: str, k: int) -> bool:
3+
n = len(s)
4+
f = [[0] * n for _ in range(n)]
5+
for i in range(n):
6+
f[i][i] = 1
7+
for i in range(n - 2, -1, -1):
8+
for j in range(i + 1, n):
9+
if s[i] == s[j]:
10+
f[i][j] = f[i + 1][j - 1] + 2
11+
else:
12+
f[i][j] = max(f[i + 1][j], f[i][j - 1])
13+
if f[i][j] + k >= n:
14+
return True
15+
return False

solution/1200-1299/1217.Minimum Cost to Move Chips to The Same Position/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767

6868
将所有偶数下标的芯片移动到 0 号位置,所有奇数下标的芯片移动到 1 号位置,所有的代价为 0,接下来只需要在 0/1 号位置中选择其中一个较小数量的芯片,移动到另一个位置。所需的最小代价就是那个较小的数量。
6969

70+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为芯片的数量。
71+
7072
<!-- tabs:start -->
7173

7274
### **Python3**

solution/1200-1299/1221.Split a String in Balanced Strings/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
**方法一:贪心**
60+
61+
我们用变量 $l$ 维护当前字符串的平衡度,即 $l$ 的值为当前字符串中 $L$ 的数量减去 $R$ 的数量。当 $l$ 的值为 0 时,我们就找到了一个平衡字符串。
62+
63+
遍历字符串 $s$,当遍历到第 $i$ 个字符时,如果 $s[i] = L$,则 $l$ 的值加 1,否则 $l$ 的值减 1。当 $l$ 的值为 0 时,我们将答案加 1。
64+
65+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
66+
5967
<!-- tabs:start -->
6068

6169
### **Python3**

0 commit comments

Comments
 (0)