Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 21f559f

Browse files
authored
feat: add solutions to lc problem: No.516 (doocs#2500)
No.516.Longest Palindromic Subsequence
1 parent 51ed782 commit 21f559f

File tree

9 files changed

+185
-88
lines changed

9 files changed

+185
-88
lines changed

solution/0500-0599/0516.Longest Palindromic Subsequence/README.md

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,44 +41,54 @@
4141

4242
## 解法
4343

44-
### 方法一
44+
### 方法一:动态规划
45+
46+
我们定义 $f[i][j]$ 表示字符串 $s$ 的第 $i$ 个字符到第 $j$ 个字符之间的最长回文子序列的长度。初始时 $f[i][i] = 1$,其余位置的值均为 $0$。
47+
48+
如果 $s[i] = s[j]$,那么 $f[i][j] = f[i + 1][j - 1] + 2$;否则 $f[i][j] = \max(f[i + 1][j], f[i][j - 1])$。
49+
50+
由于 $f[i][j]$ 的值与 $f[i + 1][j - 1]$, $f[i + 1][j]$, $f[i][j - 1]$ 有关,所以我们应该从大到小枚举 $i$,从小到大枚举 $j$。
51+
52+
答案即为 $f[0][n - 1]$。
53+
54+
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为字符串 $s$ 的长度。
4555

4656
<!-- tabs:start -->
4757

4858
```python
4959
class Solution:
5060
def longestPalindromeSubseq(self, s: str) -> int:
5161
n = len(s)
52-
dp = [[0] * n for _ in range(n)]
62+
f = [[0] * n for _ in range(n)]
5363
for i in range(n):
54-
dp[i][i] = 1
55-
for j in range(1, n):
56-
for i in range(j - 1, -1, -1):
64+
f[i][i] = 1
65+
for i in range(n - 1, -1, -1):
66+
for j in range(i + 1, n):
5767
if s[i] == s[j]:
58-
dp[i][j] = dp[i + 1][j - 1] + 2
68+
f[i][j] = f[i + 1][j - 1] + 2
5969
else:
60-
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
61-
return dp[0][-1]
70+
f[i][j] = max(f[i + 1][j], f[i][j - 1])
71+
return f[0][-1]
6272
```
6373

6474
```java
6575
class Solution {
6676
public int longestPalindromeSubseq(String s) {
6777
int n = s.length();
68-
int[][] dp = new int[n][n];
78+
int[][] f = new int[n][n];
6979
for (int i = 0; i < n; ++i) {
70-
dp[i][i] = 1;
80+
f[i][i] = 1;
7181
}
72-
for (int j = 1; j < n; ++j) {
73-
for (int i = j - 1; i >= 0; --i) {
82+
for (int i = n - 1; i >= 0; --i) {
83+
for (int j = i + 1; j < n; ++j) {
7484
if (s.charAt(i) == s.charAt(j)) {
75-
dp[i][j] = dp[i + 1][j - 1] + 2;
85+
f[i][j] = f[i + 1][j - 1] + 2;
7686
} else {
77-
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
87+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
7888
}
7989
}
8090
}
81-
return dp[0][n - 1];
91+
return f[0][n - 1];
8292
}
8393
}
8494
```
@@ -88,42 +98,63 @@ class Solution {
8898
public:
8999
int longestPalindromeSubseq(string s) {
90100
int n = s.size();
91-
vector<vector<int>> dp(n, vector<int>(n, 0));
101+
int f[n][n];
102+
memset(f, 0, sizeof(f));
92103
for (int i = 0; i < n; ++i) {
93-
dp[i][i] = 1;
104+
f[i][i] = 1;
94105
}
95-
for (int j = 1; j < n; ++j) {
96-
for (int i = j - 1; i >= 0; --i) {
106+
for (int i = n - 1; ~i; --i) {
107+
for (int j = i + 1; j < n; ++j) {
97108
if (s[i] == s[j]) {
98-
dp[i][j] = dp[i + 1][j - 1] + 2;
109+
f[i][j] = f[i + 1][j - 1] + 2;
99110
} else {
100-
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
111+
f[i][j] = max(f[i + 1][j], f[i][j - 1]);
101112
}
102113
}
103114
}
104-
return dp[0][n - 1];
115+
return f[0][n - 1];
105116
}
106117
};
107118
```
108119
109120
```go
110121
func longestPalindromeSubseq(s string) int {
111122
n := len(s)
112-
dp := make([][]int, n)
113-
for i := 0; i < n; i++ {
114-
dp[i] = make([]int, n)
115-
dp[i][i] = 1
123+
f := make([][]int, n)
124+
for i := range f {
125+
f[i] = make([]int, n)
126+
f[i][i] = 1
116127
}
117-
for j := 1; j < n; j++ {
118-
for i := j - 1; i >= 0; i-- {
128+
for i := n - 2; i >= 0; i-- {
129+
for j := i + 1; j < n; j++ {
119130
if s[i] == s[j] {
120-
dp[i][j] = dp[i+1][j-1] + 2
131+
f[i][j] = f[i+1][j-1] + 2
121132
} else {
122-
dp[i][j] = max(dp[i+1][j], dp[i][j-1])
133+
f[i][j] = max(f[i+1][j], f[i][j-1])
123134
}
124135
}
125136
}
126-
return dp[0][n-1]
137+
return f[0][n-1]
138+
}
139+
```
140+
141+
```ts
142+
function longestPalindromeSubseq(s: string): number {
143+
const n = s.length;
144+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
145+
for (let i = 0; i < n; ++i) {
146+
f[i][i] = 1;
147+
}
148+
for (let i = n - 2; ~i; --i) {
149+
for (let j = i + 1; j < n; ++j) {
150+
if (s[i] === s[j]) {
151+
f[i][j] = f[i + 1][j - 1] + 2;
152+
} else {
153+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
154+
}
155+
}
156+
}
157+
return f[0][n - 1];
127158
}
128159
```
129160

solution/0500-0599/0516.Longest Palindromic Subsequence/README_EN.md

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,44 +37,54 @@
3737

3838
## Solutions
3939

40-
### Solution 1
40+
### Solution 1: Dynamic Programming
41+
42+
We define $f[i][j]$ as the length of the longest palindromic subsequence from the $i$-th character to the $j$-th character in string $s$. Initially, $f[i][i] = 1$, and the values of other positions are all $0$.
43+
44+
If $s[i] = s[j]$, then $f[i][j] = f[i + 1][j - 1] + 2$; otherwise, $f[i][j] = \max(f[i + 1][j], f[i][j - 1])$.
45+
46+
Since the value of $f[i][j]$ is related to $f[i + 1][j - 1]$, $f[i + 1][j]$, and $f[i][j - 1]$, we should enumerate $i$ from large to small, and enumerate $j$ from small to large.
47+
48+
The answer is $f[0][n - 1]$.
49+
50+
The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Where $n$ is the length of the string $s$.
4151

4252
<!-- tabs:start -->
4353

4454
```python
4555
class Solution:
4656
def longestPalindromeSubseq(self, s: str) -> int:
4757
n = len(s)
48-
dp = [[0] * n for _ in range(n)]
58+
f = [[0] * n for _ in range(n)]
4959
for i in range(n):
50-
dp[i][i] = 1
51-
for j in range(1, n):
52-
for i in range(j - 1, -1, -1):
60+
f[i][i] = 1
61+
for i in range(n - 1, -1, -1):
62+
for j in range(i + 1, n):
5363
if s[i] == s[j]:
54-
dp[i][j] = dp[i + 1][j - 1] + 2
64+
f[i][j] = f[i + 1][j - 1] + 2
5565
else:
56-
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
57-
return dp[0][-1]
66+
f[i][j] = max(f[i + 1][j], f[i][j - 1])
67+
return f[0][-1]
5868
```
5969

6070
```java
6171
class Solution {
6272
public int longestPalindromeSubseq(String s) {
6373
int n = s.length();
64-
int[][] dp = new int[n][n];
74+
int[][] f = new int[n][n];
6575
for (int i = 0; i < n; ++i) {
66-
dp[i][i] = 1;
76+
f[i][i] = 1;
6777
}
68-
for (int j = 1; j < n; ++j) {
69-
for (int i = j - 1; i >= 0; --i) {
78+
for (int i = n - 1; i >= 0; --i) {
79+
for (int j = i + 1; j < n; ++j) {
7080
if (s.charAt(i) == s.charAt(j)) {
71-
dp[i][j] = dp[i + 1][j - 1] + 2;
81+
f[i][j] = f[i + 1][j - 1] + 2;
7282
} else {
73-
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
83+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
7484
}
7585
}
7686
}
77-
return dp[0][n - 1];
87+
return f[0][n - 1];
7888
}
7989
}
8090
```
@@ -84,42 +94,63 @@ class Solution {
8494
public:
8595
int longestPalindromeSubseq(string s) {
8696
int n = s.size();
87-
vector<vector<int>> dp(n, vector<int>(n, 0));
97+
int f[n][n];
98+
memset(f, 0, sizeof(f));
8899
for (int i = 0; i < n; ++i) {
89-
dp[i][i] = 1;
100+
f[i][i] = 1;
90101
}
91-
for (int j = 1; j < n; ++j) {
92-
for (int i = j - 1; i >= 0; --i) {
102+
for (int i = n - 1; ~i; --i) {
103+
for (int j = i + 1; j < n; ++j) {
93104
if (s[i] == s[j]) {
94-
dp[i][j] = dp[i + 1][j - 1] + 2;
105+
f[i][j] = f[i + 1][j - 1] + 2;
95106
} else {
96-
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
107+
f[i][j] = max(f[i + 1][j], f[i][j - 1]);
97108
}
98109
}
99110
}
100-
return dp[0][n - 1];
111+
return f[0][n - 1];
101112
}
102113
};
103114
```
104115
105116
```go
106117
func longestPalindromeSubseq(s string) int {
107118
n := len(s)
108-
dp := make([][]int, n)
109-
for i := 0; i < n; i++ {
110-
dp[i] = make([]int, n)
111-
dp[i][i] = 1
119+
f := make([][]int, n)
120+
for i := range f {
121+
f[i] = make([]int, n)
122+
f[i][i] = 1
112123
}
113-
for j := 1; j < n; j++ {
114-
for i := j - 1; i >= 0; i-- {
124+
for i := n - 2; i >= 0; i-- {
125+
for j := i + 1; j < n; j++ {
115126
if s[i] == s[j] {
116-
dp[i][j] = dp[i+1][j-1] + 2
127+
f[i][j] = f[i+1][j-1] + 2
117128
} else {
118-
dp[i][j] = max(dp[i+1][j], dp[i][j-1])
129+
f[i][j] = max(f[i+1][j], f[i][j-1])
119130
}
120131
}
121132
}
122-
return dp[0][n-1]
133+
return f[0][n-1]
134+
}
135+
```
136+
137+
```ts
138+
function longestPalindromeSubseq(s: string): number {
139+
const n = s.length;
140+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
141+
for (let i = 0; i < n; ++i) {
142+
f[i][i] = 1;
143+
}
144+
for (let i = n - 2; ~i; --i) {
145+
for (let j = i + 1; j < n; ++j) {
146+
if (s[i] === s[j]) {
147+
f[i][j] = f[i + 1][j - 1] + 2;
148+
} else {
149+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
150+
}
151+
}
152+
}
153+
return f[0][n - 1];
123154
}
124155
```
125156

solution/0500-0599/0516.Longest Palindromic Subsequence/Solution.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ class Solution {
22
public:
33
int longestPalindromeSubseq(string s) {
44
int n = s.size();
5-
vector<vector<int>> dp(n, vector<int>(n, 0));
5+
int f[n][n];
6+
memset(f, 0, sizeof(f));
67
for (int i = 0; i < n; ++i) {
7-
dp[i][i] = 1;
8+
f[i][i] = 1;
89
}
9-
for (int j = 1; j < n; ++j) {
10-
for (int i = j - 1; i >= 0; --i) {
10+
for (int i = n - 1; ~i; --i) {
11+
for (int j = i + 1; j < n; ++j) {
1112
if (s[i] == s[j]) {
12-
dp[i][j] = dp[i + 1][j - 1] + 2;
13+
f[i][j] = f[i + 1][j - 1] + 2;
1314
} else {
14-
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
15+
f[i][j] = max(f[i + 1][j], f[i][j - 1]);
1516
}
1617
}
1718
}
18-
return dp[0][n - 1];
19+
return f[0][n - 1];
1920
}
2021
};
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
func longestPalindromeSubseq(s string) int {
22
n := len(s)
3-
dp := make([][]int, n)
4-
for i := 0; i < n; i++ {
5-
dp[i] = make([]int, n)
6-
dp[i][i] = 1
3+
f := make([][]int, n)
4+
for i := range f {
5+
f[i] = make([]int, n)
6+
f[i][i] = 1
77
}
8-
for j := 1; j < n; j++ {
9-
for i := j - 1; i >= 0; i-- {
8+
for i := n - 2; i >= 0; i-- {
9+
for j := i + 1; j < n; j++ {
1010
if s[i] == s[j] {
11-
dp[i][j] = dp[i+1][j-1] + 2
11+
f[i][j] = f[i+1][j-1] + 2
1212
} else {
13-
dp[i][j] = max(dp[i+1][j], dp[i][j-1])
13+
f[i][j] = max(f[i+1][j], f[i][j-1])
1414
}
1515
}
1616
}
17-
return dp[0][n-1]
17+
return f[0][n-1]
1818
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
class Solution {
22
public int longestPalindromeSubseq(String s) {
33
int n = s.length();
4-
int[][] dp = new int[n][n];
4+
int[][] f = new int[n][n];
55
for (int i = 0; i < n; ++i) {
6-
dp[i][i] = 1;
6+
f[i][i] = 1;
77
}
8-
for (int j = 1; j < n; ++j) {
9-
for (int i = j - 1; i >= 0; --i) {
8+
for (int i = n - 1; i >= 0; --i) {
9+
for (int j = i + 1; j < n; ++j) {
1010
if (s.charAt(i) == s.charAt(j)) {
11-
dp[i][j] = dp[i + 1][j - 1] + 2;
11+
f[i][j] = f[i + 1][j - 1] + 2;
1212
} else {
13-
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
13+
f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]);
1414
}
1515
}
1616
}
17-
return dp[0][n - 1];
17+
return f[0][n - 1];
1818
}
1919
}

0 commit comments

Comments
 (0)