Skip to content

Commit 1faf9b5

Browse files
committed
feat: add solutions to lc problem: No.1682
No.1682.Longest Palindromic Subsequence II
1 parent 58d8540 commit 1faf9b5

File tree

7 files changed

+343
-4
lines changed

7 files changed

+343
-4
lines changed

solution/1600-1699/1682.Longest Palindromic Subsequence II/README.md

+126-1
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,147 @@
5050

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

53+
**方法一:记忆化搜索**
54+
55+
我们设计一个函数 $dfs(i, j, x)$ 表示字符串 $s$ 中下标范围 $[i, j]$ 内,且以字符 $x$ 结尾的最长“好的回文子序列”的长度。答案为 $dfs(0, n - 1, 26)$。
56+
57+
函数 $dfs(i, j, x)$ 的计算过程如下:
58+
59+
- 如果 $i >= j$,则 $dfs(i, j, x) = 0$;
60+
- 如果 $s[i] = s[j]$,且 $s[i] \neq x$,那么 $dfs(i, j, x) = dfs(i + 1, j - 1, s[i]) + 2$;
61+
- 如果 $s[i] \neq s[j]$,那么 $dfs(i, j, x) = max(dfs(i + 1, j, x), dfs(i, j - 1, x))$。
62+
63+
过程中,我们可以使用记忆化搜索的方式,避免重复计算。
64+
65+
时间复杂度 $O(n^2 \times C)$。其中 $n$ 为字符串 $s$ 的长度,而 $C$ 为字符集大小。本题中 $C = 26$。
66+
5367
<!-- tabs:start -->
5468

5569
### **Python3**
5670

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

5973
```python
60-
74+
class Solution:
75+
def longestPalindromeSubseq(self, s: str) -> int:
76+
@cache
77+
def dfs(i, j, x):
78+
if i >= j:
79+
return 0
80+
if s[i] == s[j] and s[i] != x:
81+
return dfs(i + 1, j - 1, s[i]) + 2
82+
return max(dfs(i + 1, j, x), dfs(i, j - 1, x))
83+
84+
ans = dfs(0, len(s) - 1, '')
85+
dfs.cache_clear()
86+
return ans
6187
```
6288

6389
### **Java**
6490

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

6793
```java
94+
class Solution {
95+
private int[][][] f;
96+
private String s;
97+
98+
public int longestPalindromeSubseq(String s) {
99+
int n = s.length();
100+
this.s = s;
101+
f = new int[n][n][27];
102+
for (var a : f) {
103+
for (var b : a) {
104+
Arrays.fill(b, -1);
105+
}
106+
}
107+
return dfs(0, n - 1, 26);
108+
}
109+
110+
private int dfs(int i, int j, int x) {
111+
if (i >= j) {
112+
return 0;
113+
}
114+
if (f[i][j][x] != -1) {
115+
return f[i][j][x];
116+
}
117+
int ans = 0;
118+
if (s.charAt(i) == s.charAt(j) && s.charAt(i) - 'a' != x) {
119+
ans = dfs(i + 1, j - 1, s.charAt(i) - 'a') + 2;
120+
} else {
121+
ans = Math.max(dfs(i + 1, j, x), dfs(i, j - 1, x));
122+
}
123+
f[i][j][x] = ans;
124+
return ans;
125+
}
126+
}
127+
```
128+
129+
### **C++**
130+
131+
```cpp
132+
class Solution {
133+
public:
134+
int f[251][251][27];
135+
136+
int longestPalindromeSubseq(string s) {
137+
int n = s.size();
138+
memset(f, -1, sizeof f);
139+
function<int(int, int, int)> dfs = [&](int i, int j, int x) -> int {
140+
if (i >= j) return 0;
141+
if (f[i][j][x] != -1) return f[i][j][x];
142+
int ans = 0;
143+
if (s[i] == s[j] && s[i] - 'a' != x) ans = dfs(i + 1, j - 1, s[i] - 'a') + 2;
144+
else ans = max(dfs(i + 1, j, x), dfs(i, j - 1, x));
145+
f[i][j][x] = ans;
146+
return ans;
147+
};
148+
return dfs(0, n - 1, 26);
149+
}
150+
};
151+
```
68152

153+
### **Go**
154+
155+
```go
156+
func longestPalindromeSubseq(s string) int {
157+
n := len(s)
158+
f := make([][][]int, n)
159+
for i := range f {
160+
f[i] = make([][]int, n)
161+
for j := range f[i] {
162+
f[i][j] = make([]int, 27)
163+
for k := range f[i][j] {
164+
f[i][j][k] = -1
165+
}
166+
}
167+
}
168+
var dfs func(i, j, x int) int
169+
dfs = func(i, j, x int) int {
170+
if i >= j {
171+
return 0
172+
}
173+
if f[i][j][x] != -1 {
174+
return f[i][j][x]
175+
}
176+
ans := 0
177+
if s[i] == s[j] && int(s[i]-'a') != x {
178+
ans = dfs(i+1, j-1, int(s[i]-'a')) + 2
179+
} else {
180+
ans = max(dfs(i+1, j, x), dfs(i, j-1, x))
181+
}
182+
f[i][j][x] = ans
183+
return ans
184+
}
185+
return dfs(0, n-1, 26)
186+
}
187+
188+
func max(a, b int) int {
189+
if a > b {
190+
return a
191+
}
192+
return b
193+
}
69194
```
70195

71196
### **...**

solution/1600-1699/1682.Longest Palindromic Subsequence II/README_EN.md

+112-1
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,124 @@
4949
### **Python3**
5050

5151
```python
52-
52+
class Solution:
53+
def longestPalindromeSubseq(self, s: str) -> int:
54+
@cache
55+
def dfs(i, j, x):
56+
if i >= j:
57+
return 0
58+
if s[i] == s[j] and s[i] != x:
59+
return dfs(i + 1, j - 1, s[i]) + 2
60+
return max(dfs(i + 1, j, x), dfs(i, j - 1, x))
61+
62+
ans = dfs(0, len(s) - 1, '')
63+
dfs.cache_clear()
64+
return ans
5365
```
5466

5567
### **Java**
5668

5769
```java
70+
class Solution {
71+
private int[][][] f;
72+
private String s;
73+
74+
public int longestPalindromeSubseq(String s) {
75+
int n = s.length();
76+
this.s = s;
77+
f = new int[n][n][27];
78+
for (var a : f) {
79+
for (var b : a) {
80+
Arrays.fill(b, -1);
81+
}
82+
}
83+
return dfs(0, n - 1, 26);
84+
}
85+
86+
private int dfs(int i, int j, int x) {
87+
if (i >= j) {
88+
return 0;
89+
}
90+
if (f[i][j][x] != -1) {
91+
return f[i][j][x];
92+
}
93+
int ans = 0;
94+
if (s.charAt(i) == s.charAt(j) && s.charAt(i) - 'a' != x) {
95+
ans = dfs(i + 1, j - 1, s.charAt(i) - 'a') + 2;
96+
} else {
97+
ans = Math.max(dfs(i + 1, j, x), dfs(i, j - 1, x));
98+
}
99+
f[i][j][x] = ans;
100+
return ans;
101+
}
102+
}
103+
```
104+
105+
### **C++**
106+
107+
```cpp
108+
class Solution {
109+
public:
110+
int f[251][251][27];
111+
112+
int longestPalindromeSubseq(string s) {
113+
int n = s.size();
114+
memset(f, -1, sizeof f);
115+
function<int(int, int, int)> dfs = [&](int i, int j, int x) -> int {
116+
if (i >= j) return 0;
117+
if (f[i][j][x] != -1) return f[i][j][x];
118+
int ans = 0;
119+
if (s[i] == s[j] && s[i] - 'a' != x) ans = dfs(i + 1, j - 1, s[i] - 'a') + 2;
120+
else ans = max(dfs(i + 1, j, x), dfs(i, j - 1, x));
121+
f[i][j][x] = ans;
122+
return ans;
123+
};
124+
return dfs(0, n - 1, 26);
125+
}
126+
};
127+
```
58128

129+
### **Go**
130+
131+
```go
132+
func longestPalindromeSubseq(s string) int {
133+
n := len(s)
134+
f := make([][][]int, n)
135+
for i := range f {
136+
f[i] = make([][]int, n)
137+
for j := range f[i] {
138+
f[i][j] = make([]int, 27)
139+
for k := range f[i][j] {
140+
f[i][j][k] = -1
141+
}
142+
}
143+
}
144+
var dfs func(i, j, x int) int
145+
dfs = func(i, j, x int) int {
146+
if i >= j {
147+
return 0
148+
}
149+
if f[i][j][x] != -1 {
150+
return f[i][j][x]
151+
}
152+
ans := 0
153+
if s[i] == s[j] && int(s[i]-'a') != x {
154+
ans = dfs(i+1, j-1, int(s[i]-'a')) + 2
155+
} else {
156+
ans = max(dfs(i+1, j, x), dfs(i, j-1, x))
157+
}
158+
f[i][j][x] = ans
159+
return ans
160+
}
161+
return dfs(0, n-1, 26)
162+
}
163+
164+
func max(a, b int) int {
165+
if a > b {
166+
return a
167+
}
168+
return b
169+
}
59170
```
60171

61172
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public:
3+
int f[251][251][27];
4+
5+
int longestPalindromeSubseq(string s) {
6+
int n = s.size();
7+
memset(f, -1, sizeof f);
8+
function<int(int, int, int)> dfs = [&](int i, int j, int x) -> int {
9+
if (i >= j) return 0;
10+
if (f[i][j][x] != -1) return f[i][j][x];
11+
int ans = 0;
12+
if (s[i] == s[j] && s[i] - 'a' != x) ans = dfs(i + 1, j - 1, s[i] - 'a') + 2;
13+
else ans = max(dfs(i + 1, j, x), dfs(i, j - 1, x));
14+
f[i][j][x] = ans;
15+
return ans;
16+
};
17+
return dfs(0, n - 1, 26);
18+
}
19+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
func longestPalindromeSubseq(s string) int {
2+
n := len(s)
3+
f := make([][][]int, n)
4+
for i := range f {
5+
f[i] = make([][]int, n)
6+
for j := range f[i] {
7+
f[i][j] = make([]int, 27)
8+
for k := range f[i][j] {
9+
f[i][j][k] = -1
10+
}
11+
}
12+
}
13+
var dfs func(i, j, x int) int
14+
dfs = func(i, j, x int) int {
15+
if i >= j {
16+
return 0
17+
}
18+
if f[i][j][x] != -1 {
19+
return f[i][j][x]
20+
}
21+
ans := 0
22+
if s[i] == s[j] && int(s[i]-'a') != x {
23+
ans = dfs(i+1, j-1, int(s[i]-'a')) + 2
24+
} else {
25+
ans = max(dfs(i+1, j, x), dfs(i, j-1, x))
26+
}
27+
f[i][j][x] = ans
28+
return ans
29+
}
30+
return dfs(0, n-1, 26)
31+
}
32+
33+
func max(a, b int) int {
34+
if a > b {
35+
return a
36+
}
37+
return b
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution {
2+
private int[][][] f;
3+
private String s;
4+
5+
public int longestPalindromeSubseq(String s) {
6+
int n = s.length();
7+
this.s = s;
8+
f = new int[n][n][27];
9+
for (var a : f) {
10+
for (var b : a) {
11+
Arrays.fill(b, -1);
12+
}
13+
}
14+
return dfs(0, n - 1, 26);
15+
}
16+
17+
private int dfs(int i, int j, int x) {
18+
if (i >= j) {
19+
return 0;
20+
}
21+
if (f[i][j][x] != -1) {
22+
return f[i][j][x];
23+
}
24+
int ans = 0;
25+
if (s.charAt(i) == s.charAt(j) && s.charAt(i) - 'a' != x) {
26+
ans = dfs(i + 1, j - 1, s.charAt(i) - 'a') + 2;
27+
} else {
28+
ans = Math.max(dfs(i + 1, j, x), dfs(i, j - 1, x));
29+
}
30+
f[i][j][x] = ans;
31+
return ans;
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution:
2+
def longestPalindromeSubseq(self, s: str) -> int:
3+
@cache
4+
def dfs(i, j, x):
5+
if i >= j:
6+
return 0
7+
if s[i] == s[j] and s[i] != x:
8+
return dfs(i + 1, j - 1, s[i]) + 2
9+
return max(dfs(i + 1, j, x), dfs(i, j - 1, x))
10+
11+
ans = dfs(0, len(s) - 1, '')
12+
dfs.cache_clear()
13+
return ans

0 commit comments

Comments
 (0)