Skip to content
/ leetcode Public
  • Sponsor doocs/leetcode

  • Notifications You must be signed in to change notification settings
  • Fork 8.9k

Commit ee4e016

Browse files
authoredMar 30, 2025··
feat: add solutions to lc problems: No.3503,3504 (#4313)
* No.3503.Longest Palindrome After Substring Concatenation I * No.3504.Longest Palindrome After Substring Concatenation II
1 parent 291a680 commit ee4e016

File tree

14 files changed

+1192
-12
lines changed

14 files changed

+1192
-12
lines changed
 

‎solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README.md

+200-3
Original file line numberDiff line numberDiff line change
@@ -96,25 +96,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3503.Lo
9696
#### Python3
9797

9898
```python
99-
99+
class Solution:
100+
def longestPalindrome(self, s: str, t: str) -> int:
101+
def expand(s: str, g: List[int], l: int, r: int):
102+
while l >= 0 and r < len(s) and s[l] == s[r]:
103+
g[l] = max(g[l], r - l + 1)
104+
l, r = l - 1, r + 1
105+
106+
def calc(s: str) -> List[int]:
107+
n = len(s)
108+
g = [0] * n
109+
for i in range(n):
110+
expand(s, g, i, i)
111+
expand(s, g, i, i + 1)
112+
return g
113+
114+
m, n = len(s), len(t)
115+
t = t[::-1]
116+
g1, g2 = calc(s), calc(t)
117+
ans = max(*g1, *g2)
118+
f = [[0] * (n + 1) for _ in range(m + 1)]
119+
for i, a in enumerate(s, 1):
120+
for j, b in enumerate(t, 1):
121+
if a == b:
122+
f[i][j] = f[i - 1][j - 1] + 1
123+
ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i]))
124+
ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j]))
125+
return ans
100126
```
101127

102128
#### Java
103129

104130
```java
105-
131+
class Solution {
132+
public int longestPalindrome(String S, String T) {
133+
char[] s = S.toCharArray();
134+
char[] t = new StringBuilder(T).reverse().toString().toCharArray();
135+
int m = s.length, n = t.length;
136+
int[] g1 = calc(s), g2 = calc(t);
137+
int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt());
138+
int[][] f = new int[m + 1][n + 1];
139+
for (int i = 1; i <= m; ++i) {
140+
for (int j = 1; j <= n; ++j) {
141+
if (s[i - 1] == t[j - 1]) {
142+
f[i][j] = f[i - 1][j - 1] + 1;
143+
ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
144+
ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
145+
}
146+
}
147+
}
148+
return ans;
149+
}
150+
151+
private void expand(char[] s, int[] g, int l, int r) {
152+
while (l >= 0 && r < s.length && s[l] == s[r]) {
153+
g[l] = Math.max(g[l], r - l + 1);
154+
--l;
155+
++r;
156+
}
157+
}
158+
159+
private int[] calc(char[] s) {
160+
int n = s.length;
161+
int[] g = new int[n];
162+
for (int i = 0; i < n; ++i) {
163+
expand(s, g, i, i);
164+
expand(s, g, i, i + 1);
165+
}
166+
return g;
167+
}
168+
}
106169
```
107170

108171
#### C++
109172

110173
```cpp
111-
174+
class Solution {
175+
public:
176+
int longestPalindrome(string s, string t) {
177+
int m = s.size(), n = t.size();
178+
ranges::reverse(t);
179+
vector<int> g1 = calc(s), g2 = calc(t);
180+
int ans = max(ranges::max(g1), ranges::max(g2));
181+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
182+
for (int i = 1; i <= m; ++i) {
183+
for (int j = 1; j <= n; ++j) {
184+
if (s[i - 1] == t[j - 1]) {
185+
f[i][j] = f[i - 1][j - 1] + 1;
186+
ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
187+
ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
188+
}
189+
}
190+
}
191+
return ans;
192+
}
193+
194+
private:
195+
void expand(const string& s, vector<int>& g, int l, int r) {
196+
while (l >= 0 && r < s.size() && s[l] == s[r]) {
197+
g[l] = max(g[l], r - l + 1);
198+
--l;
199+
++r;
200+
}
201+
}
202+
203+
vector<int> calc(const string& s) {
204+
int n = s.size();
205+
vector<int> g(n, 0);
206+
for (int i = 0; i < n; ++i) {
207+
expand(s, g, i, i);
208+
expand(s, g, i, i + 1);
209+
}
210+
return g;
211+
}
212+
};
112213
```
113214

114215
#### Go
115216

116217
```go
218+
func longestPalindrome(s, t string) int {
219+
m, n := len(s), len(t)
220+
t = reverse(t)
221+
222+
g1, g2 := calc(s), calc(t)
223+
ans := max(slices.Max(g1), slices.Max(g2))
224+
225+
f := make([][]int, m+1)
226+
for i := range f {
227+
f[i] = make([]int, n+1)
228+
}
229+
230+
for i := 1; i <= m; i++ {
231+
for j := 1; j <= n; j++ {
232+
if s[i-1] == t[j-1] {
233+
f[i][j] = f[i-1][j-1] + 1
234+
a, b := 0, 0
235+
if i < m {
236+
a = g1[i]
237+
}
238+
if j < n {
239+
b = g2[j]
240+
}
241+
ans = max(ans, f[i][j]*2+a)
242+
ans = max(ans, f[i][j]*2+b)
243+
}
244+
}
245+
}
246+
return ans
247+
}
248+
249+
func calc(s string) []int {
250+
n, g := len(s), make([]int, len(s))
251+
for i := 0; i < n; i++ {
252+
expand(s, g, i, i)
253+
expand(s, g, i, i+1)
254+
}
255+
return g
256+
}
257+
258+
func expand(s string, g []int, l, r int) {
259+
for l >= 0 && r < len(s) && s[l] == s[r] {
260+
g[l] = max(g[l], r-l+1)
261+
l, r = l-1, r+1
262+
}
263+
}
264+
265+
func reverse(s string) string {
266+
r := []rune(s)
267+
slices.Reverse(r)
268+
return string(r)
269+
}
270+
```
117271

272+
#### TypeScript
273+
274+
```ts
275+
function longestPalindrome(s: string, t: string): number {
276+
function expand(s: string, g: number[], l: number, r: number): void {
277+
while (l >= 0 && r < s.length && s[l] === s[r]) {
278+
g[l] = Math.max(g[l], r - l + 1);
279+
l--;
280+
r++;
281+
}
282+
}
283+
284+
function calc(s: string): number[] {
285+
const n = s.length;
286+
const g: number[] = Array(n).fill(0);
287+
for (let i = 0; i < n; i++) {
288+
expand(s, g, i, i);
289+
expand(s, g, i, i + 1);
290+
}
291+
return g;
292+
}
293+
294+
const m = s.length,
295+
n = t.length;
296+
t = t.split('').reverse().join('');
297+
const g1 = calc(s);
298+
const g2 = calc(t);
299+
let ans = Math.max(...g1, ...g2);
300+
301+
const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
302+
303+
for (let i = 1; i <= m; i++) {
304+
for (let j = 1; j <= n; j++) {
305+
if (s[i - 1] === t[j - 1]) {
306+
f[i][j] = f[i - 1][j - 1] + 1;
307+
ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i]));
308+
ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j]));
309+
}
310+
}
311+
}
312+
313+
return ans;
314+
}
118315
```
119316

120317
<!-- tabs:end -->

‎solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README_EN.md

+200-3
Original file line numberDiff line numberDiff line change
@@ -94,25 +94,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3503.Lo
9494
#### Python3
9595

9696
```python
97-
97+
class Solution:
98+
def longestPalindrome(self, s: str, t: str) -> int:
99+
def expand(s: str, g: List[int], l: int, r: int):
100+
while l >= 0 and r < len(s) and s[l] == s[r]:
101+
g[l] = max(g[l], r - l + 1)
102+
l, r = l - 1, r + 1
103+
104+
def calc(s: str) -> List[int]:
105+
n = len(s)
106+
g = [0] * n
107+
for i in range(n):
108+
expand(s, g, i, i)
109+
expand(s, g, i, i + 1)
110+
return g
111+
112+
m, n = len(s), len(t)
113+
t = t[::-1]
114+
g1, g2 = calc(s), calc(t)
115+
ans = max(*g1, *g2)
116+
f = [[0] * (n + 1) for _ in range(m + 1)]
117+
for i, a in enumerate(s, 1):
118+
for j, b in enumerate(t, 1):
119+
if a == b:
120+
f[i][j] = f[i - 1][j - 1] + 1
121+
ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i]))
122+
ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j]))
123+
return ans
98124
```
99125

100126
#### Java
101127

102128
```java
103-
129+
class Solution {
130+
public int longestPalindrome(String S, String T) {
131+
char[] s = S.toCharArray();
132+
char[] t = new StringBuilder(T).reverse().toString().toCharArray();
133+
int m = s.length, n = t.length;
134+
int[] g1 = calc(s), g2 = calc(t);
135+
int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt());
136+
int[][] f = new int[m + 1][n + 1];
137+
for (int i = 1; i <= m; ++i) {
138+
for (int j = 1; j <= n; ++j) {
139+
if (s[i - 1] == t[j - 1]) {
140+
f[i][j] = f[i - 1][j - 1] + 1;
141+
ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
142+
ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
143+
}
144+
}
145+
}
146+
return ans;
147+
}
148+
149+
private void expand(char[] s, int[] g, int l, int r) {
150+
while (l >= 0 && r < s.length && s[l] == s[r]) {
151+
g[l] = Math.max(g[l], r - l + 1);
152+
--l;
153+
++r;
154+
}
155+
}
156+
157+
private int[] calc(char[] s) {
158+
int n = s.length;
159+
int[] g = new int[n];
160+
for (int i = 0; i < n; ++i) {
161+
expand(s, g, i, i);
162+
expand(s, g, i, i + 1);
163+
}
164+
return g;
165+
}
166+
}
104167
```
105168

106169
#### C++
107170

108171
```cpp
109-
172+
class Solution {
173+
public:
174+
int longestPalindrome(string s, string t) {
175+
int m = s.size(), n = t.size();
176+
ranges::reverse(t);
177+
vector<int> g1 = calc(s), g2 = calc(t);
178+
int ans = max(ranges::max(g1), ranges::max(g2));
179+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
180+
for (int i = 1; i <= m; ++i) {
181+
for (int j = 1; j <= n; ++j) {
182+
if (s[i - 1] == t[j - 1]) {
183+
f[i][j] = f[i - 1][j - 1] + 1;
184+
ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
185+
ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
186+
}
187+
}
188+
}
189+
return ans;
190+
}
191+
192+
private:
193+
void expand(const string& s, vector<int>& g, int l, int r) {
194+
while (l >= 0 && r < s.size() && s[l] == s[r]) {
195+
g[l] = max(g[l], r - l + 1);
196+
--l;
197+
++r;
198+
}
199+
}
200+
201+
vector<int> calc(const string& s) {
202+
int n = s.size();
203+
vector<int> g(n, 0);
204+
for (int i = 0; i < n; ++i) {
205+
expand(s, g, i, i);
206+
expand(s, g, i, i + 1);
207+
}
208+
return g;
209+
}
210+
};
110211
```
111212

112213
#### Go
113214

114215
```go
216+
func longestPalindrome(s, t string) int {
217+
m, n := len(s), len(t)
218+
t = reverse(t)
219+
220+
g1, g2 := calc(s), calc(t)
221+
ans := max(slices.Max(g1), slices.Max(g2))
222+
223+
f := make([][]int, m+1)
224+
for i := range f {
225+
f[i] = make([]int, n+1)
226+
}
227+
228+
for i := 1; i <= m; i++ {
229+
for j := 1; j <= n; j++ {
230+
if s[i-1] == t[j-1] {
231+
f[i][j] = f[i-1][j-1] + 1
232+
a, b := 0, 0
233+
if i < m {
234+
a = g1[i]
235+
}
236+
if j < n {
237+
b = g2[j]
238+
}
239+
ans = max(ans, f[i][j]*2+a)
240+
ans = max(ans, f[i][j]*2+b)
241+
}
242+
}
243+
}
244+
return ans
245+
}
246+
247+
func calc(s string) []int {
248+
n, g := len(s), make([]int, len(s))
249+
for i := 0; i < n; i++ {
250+
expand(s, g, i, i)
251+
expand(s, g, i, i+1)
252+
}
253+
return g
254+
}
255+
256+
func expand(s string, g []int, l, r int) {
257+
for l >= 0 && r < len(s) && s[l] == s[r] {
258+
g[l] = max(g[l], r-l+1)
259+
l, r = l-1, r+1
260+
}
261+
}
262+
263+
func reverse(s string) string {
264+
r := []rune(s)
265+
slices.Reverse(r)
266+
return string(r)
267+
}
268+
```
115269

270+
#### TypeScript
271+
272+
```ts
273+
function longestPalindrome(s: string, t: string): number {
274+
function expand(s: string, g: number[], l: number, r: number): void {
275+
while (l >= 0 && r < s.length && s[l] === s[r]) {
276+
g[l] = Math.max(g[l], r - l + 1);
277+
l--;
278+
r++;
279+
}
280+
}
281+
282+
function calc(s: string): number[] {
283+
const n = s.length;
284+
const g: number[] = Array(n).fill(0);
285+
for (let i = 0; i < n; i++) {
286+
expand(s, g, i, i);
287+
expand(s, g, i, i + 1);
288+
}
289+
return g;
290+
}
291+
292+
const m = s.length,
293+
n = t.length;
294+
t = t.split('').reverse().join('');
295+
const g1 = calc(s);
296+
const g2 = calc(t);
297+
let ans = Math.max(...g1, ...g2);
298+
299+
const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
300+
301+
for (let i = 1; i <= m; i++) {
302+
for (let j = 1; j <= n; j++) {
303+
if (s[i - 1] === t[j - 1]) {
304+
f[i][j] = f[i - 1][j - 1] + 1;
305+
ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i]));
306+
ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j]));
307+
}
308+
}
309+
}
310+
311+
return ans;
312+
}
116313
```
117314

118315
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
public:
3+
int longestPalindrome(string s, string t) {
4+
int m = s.size(), n = t.size();
5+
ranges::reverse(t);
6+
vector<int> g1 = calc(s), g2 = calc(t);
7+
int ans = max(ranges::max(g1), ranges::max(g2));
8+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
9+
for (int i = 1; i <= m; ++i) {
10+
for (int j = 1; j <= n; ++j) {
11+
if (s[i - 1] == t[j - 1]) {
12+
f[i][j] = f[i - 1][j - 1] + 1;
13+
ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
14+
ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
15+
}
16+
}
17+
}
18+
return ans;
19+
}
20+
21+
private:
22+
void expand(const string& s, vector<int>& g, int l, int r) {
23+
while (l >= 0 && r < s.size() && s[l] == s[r]) {
24+
g[l] = max(g[l], r - l + 1);
25+
--l;
26+
++r;
27+
}
28+
}
29+
30+
vector<int> calc(const string& s) {
31+
int n = s.size();
32+
vector<int> g(n, 0);
33+
for (int i = 0; i < n; ++i) {
34+
expand(s, g, i, i);
35+
expand(s, g, i, i + 1);
36+
}
37+
return g;
38+
}
39+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
func longestPalindrome(s, t string) int {
2+
m, n := len(s), len(t)
3+
t = reverse(t)
4+
5+
g1, g2 := calc(s), calc(t)
6+
ans := max(slices.Max(g1), slices.Max(g2))
7+
8+
f := make([][]int, m+1)
9+
for i := range f {
10+
f[i] = make([]int, n+1)
11+
}
12+
13+
for i := 1; i <= m; i++ {
14+
for j := 1; j <= n; j++ {
15+
if s[i-1] == t[j-1] {
16+
f[i][j] = f[i-1][j-1] + 1
17+
a, b := 0, 0
18+
if i < m {
19+
a = g1[i]
20+
}
21+
if j < n {
22+
b = g2[j]
23+
}
24+
ans = max(ans, f[i][j]*2+a)
25+
ans = max(ans, f[i][j]*2+b)
26+
}
27+
}
28+
}
29+
return ans
30+
}
31+
32+
func calc(s string) []int {
33+
n, g := len(s), make([]int, len(s))
34+
for i := 0; i < n; i++ {
35+
expand(s, g, i, i)
36+
expand(s, g, i, i+1)
37+
}
38+
return g
39+
}
40+
41+
func expand(s string, g []int, l, r int) {
42+
for l >= 0 && r < len(s) && s[l] == s[r] {
43+
g[l] = max(g[l], r-l+1)
44+
l, r = l-1, r+1
45+
}
46+
}
47+
48+
func reverse(s string) string {
49+
r := []rune(s)
50+
slices.Reverse(r)
51+
return string(r)
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution {
2+
public int longestPalindrome(String S, String T) {
3+
char[] s = S.toCharArray();
4+
char[] t = new StringBuilder(T).reverse().toString().toCharArray();
5+
int m = s.length, n = t.length;
6+
int[] g1 = calc(s), g2 = calc(t);
7+
int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt());
8+
int[][] f = new int[m + 1][n + 1];
9+
for (int i = 1; i <= m; ++i) {
10+
for (int j = 1; j <= n; ++j) {
11+
if (s[i - 1] == t[j - 1]) {
12+
f[i][j] = f[i - 1][j - 1] + 1;
13+
ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
14+
ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
15+
}
16+
}
17+
}
18+
return ans;
19+
}
20+
21+
private void expand(char[] s, int[] g, int l, int r) {
22+
while (l >= 0 && r < s.length && s[l] == s[r]) {
23+
g[l] = Math.max(g[l], r - l + 1);
24+
--l;
25+
++r;
26+
}
27+
}
28+
29+
private int[] calc(char[] s) {
30+
int n = s.length;
31+
int[] g = new int[n];
32+
for (int i = 0; i < n; ++i) {
33+
expand(s, g, i, i);
34+
expand(s, g, i, i + 1);
35+
}
36+
return g;
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution:
2+
def longestPalindrome(self, s: str, t: str) -> int:
3+
def expand(s: str, g: List[int], l: int, r: int):
4+
while l >= 0 and r < len(s) and s[l] == s[r]:
5+
g[l] = max(g[l], r - l + 1)
6+
l, r = l - 1, r + 1
7+
8+
def calc(s: str) -> List[int]:
9+
n = len(s)
10+
g = [0] * n
11+
for i in range(n):
12+
expand(s, g, i, i)
13+
expand(s, g, i, i + 1)
14+
return g
15+
16+
m, n = len(s), len(t)
17+
t = t[::-1]
18+
g1, g2 = calc(s), calc(t)
19+
ans = max(*g1, *g2)
20+
f = [[0] * (n + 1) for _ in range(m + 1)]
21+
for i, a in enumerate(s, 1):
22+
for j, b in enumerate(t, 1):
23+
if a == b:
24+
f[i][j] = f[i - 1][j - 1] + 1
25+
ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i]))
26+
ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j]))
27+
return ans
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
function longestPalindrome(s: string, t: string): number {
2+
function expand(s: string, g: number[], l: number, r: number): void {
3+
while (l >= 0 && r < s.length && s[l] === s[r]) {
4+
g[l] = Math.max(g[l], r - l + 1);
5+
l--;
6+
r++;
7+
}
8+
}
9+
10+
function calc(s: string): number[] {
11+
const n = s.length;
12+
const g: number[] = Array(n).fill(0);
13+
for (let i = 0; i < n; i++) {
14+
expand(s, g, i, i);
15+
expand(s, g, i, i + 1);
16+
}
17+
return g;
18+
}
19+
20+
const m = s.length,
21+
n = t.length;
22+
t = t.split('').reverse().join('');
23+
const g1 = calc(s);
24+
const g2 = calc(t);
25+
let ans = Math.max(...g1, ...g2);
26+
27+
const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
28+
29+
for (let i = 1; i <= m; i++) {
30+
for (let j = 1; j <= n; j++) {
31+
if (s[i - 1] === t[j - 1]) {
32+
f[i][j] = f[i - 1][j - 1] + 1;
33+
ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i]));
34+
ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j]));
35+
}
36+
}
37+
}
38+
39+
return ans;
40+
}

‎solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README.md

+200-3
Original file line numberDiff line numberDiff line change
@@ -97,25 +97,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3504.Lo
9797
#### Python3
9898

9999
```python
100-
100+
class Solution:
101+
def longestPalindrome(self, s: str, t: str) -> int:
102+
def expand(s: str, g: List[int], l: int, r: int):
103+
while l >= 0 and r < len(s) and s[l] == s[r]:
104+
g[l] = max(g[l], r - l + 1)
105+
l, r = l - 1, r + 1
106+
107+
def calc(s: str) -> List[int]:
108+
n = len(s)
109+
g = [0] * n
110+
for i in range(n):
111+
expand(s, g, i, i)
112+
expand(s, g, i, i + 1)
113+
return g
114+
115+
m, n = len(s), len(t)
116+
t = t[::-1]
117+
g1, g2 = calc(s), calc(t)
118+
ans = max(*g1, *g2)
119+
f = [[0] * (n + 1) for _ in range(m + 1)]
120+
for i, a in enumerate(s, 1):
121+
for j, b in enumerate(t, 1):
122+
if a == b:
123+
f[i][j] = f[i - 1][j - 1] + 1
124+
ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i]))
125+
ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j]))
126+
return ans
101127
```
102128

103129
#### Java
104130

105131
```java
106-
132+
class Solution {
133+
public int longestPalindrome(String S, String T) {
134+
char[] s = S.toCharArray();
135+
char[] t = new StringBuilder(T).reverse().toString().toCharArray();
136+
int m = s.length, n = t.length;
137+
int[] g1 = calc(s), g2 = calc(t);
138+
int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt());
139+
int[][] f = new int[m + 1][n + 1];
140+
for (int i = 1; i <= m; ++i) {
141+
for (int j = 1; j <= n; ++j) {
142+
if (s[i - 1] == t[j - 1]) {
143+
f[i][j] = f[i - 1][j - 1] + 1;
144+
ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
145+
ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
146+
}
147+
}
148+
}
149+
return ans;
150+
}
151+
152+
private void expand(char[] s, int[] g, int l, int r) {
153+
while (l >= 0 && r < s.length && s[l] == s[r]) {
154+
g[l] = Math.max(g[l], r - l + 1);
155+
--l;
156+
++r;
157+
}
158+
}
159+
160+
private int[] calc(char[] s) {
161+
int n = s.length;
162+
int[] g = new int[n];
163+
for (int i = 0; i < n; ++i) {
164+
expand(s, g, i, i);
165+
expand(s, g, i, i + 1);
166+
}
167+
return g;
168+
}
169+
}
107170
```
108171

109172
#### C++
110173

111174
```cpp
112-
175+
class Solution {
176+
public:
177+
int longestPalindrome(string s, string t) {
178+
int m = s.size(), n = t.size();
179+
ranges::reverse(t);
180+
vector<int> g1 = calc(s), g2 = calc(t);
181+
int ans = max(ranges::max(g1), ranges::max(g2));
182+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
183+
for (int i = 1; i <= m; ++i) {
184+
for (int j = 1; j <= n; ++j) {
185+
if (s[i - 1] == t[j - 1]) {
186+
f[i][j] = f[i - 1][j - 1] + 1;
187+
ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
188+
ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
189+
}
190+
}
191+
}
192+
return ans;
193+
}
194+
195+
private:
196+
void expand(const string& s, vector<int>& g, int l, int r) {
197+
while (l >= 0 && r < s.size() && s[l] == s[r]) {
198+
g[l] = max(g[l], r - l + 1);
199+
--l;
200+
++r;
201+
}
202+
}
203+
204+
vector<int> calc(const string& s) {
205+
int n = s.size();
206+
vector<int> g(n, 0);
207+
for (int i = 0; i < n; ++i) {
208+
expand(s, g, i, i);
209+
expand(s, g, i, i + 1);
210+
}
211+
return g;
212+
}
213+
};
113214
```
114215

115216
#### Go
116217

117218
```go
219+
func longestPalindrome(s, t string) int {
220+
m, n := len(s), len(t)
221+
t = reverse(t)
222+
223+
g1, g2 := calc(s), calc(t)
224+
ans := max(slices.Max(g1), slices.Max(g2))
225+
226+
f := make([][]int, m+1)
227+
for i := range f {
228+
f[i] = make([]int, n+1)
229+
}
230+
231+
for i := 1; i <= m; i++ {
232+
for j := 1; j <= n; j++ {
233+
if s[i-1] == t[j-1] {
234+
f[i][j] = f[i-1][j-1] + 1
235+
a, b := 0, 0
236+
if i < m {
237+
a = g1[i]
238+
}
239+
if j < n {
240+
b = g2[j]
241+
}
242+
ans = max(ans, f[i][j]*2+a)
243+
ans = max(ans, f[i][j]*2+b)
244+
}
245+
}
246+
}
247+
return ans
248+
}
249+
250+
func calc(s string) []int {
251+
n, g := len(s), make([]int, len(s))
252+
for i := 0; i < n; i++ {
253+
expand(s, g, i, i)
254+
expand(s, g, i, i+1)
255+
}
256+
return g
257+
}
258+
259+
func expand(s string, g []int, l, r int) {
260+
for l >= 0 && r < len(s) && s[l] == s[r] {
261+
g[l] = max(g[l], r-l+1)
262+
l, r = l-1, r+1
263+
}
264+
}
265+
266+
func reverse(s string) string {
267+
r := []rune(s)
268+
slices.Reverse(r)
269+
return string(r)
270+
}
271+
```
118272

273+
#### TypeScript
274+
275+
```ts
276+
function longestPalindrome(s: string, t: string): number {
277+
function expand(s: string, g: number[], l: number, r: number): void {
278+
while (l >= 0 && r < s.length && s[l] === s[r]) {
279+
g[l] = Math.max(g[l], r - l + 1);
280+
l--;
281+
r++;
282+
}
283+
}
284+
285+
function calc(s: string): number[] {
286+
const n = s.length;
287+
const g: number[] = Array(n).fill(0);
288+
for (let i = 0; i < n; i++) {
289+
expand(s, g, i, i);
290+
expand(s, g, i, i + 1);
291+
}
292+
return g;
293+
}
294+
295+
const m = s.length,
296+
n = t.length;
297+
t = t.split('').reverse().join('');
298+
const g1 = calc(s);
299+
const g2 = calc(t);
300+
let ans = Math.max(...g1, ...g2);
301+
302+
const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
303+
304+
for (let i = 1; i <= m; i++) {
305+
for (let j = 1; j <= n; j++) {
306+
if (s[i - 1] === t[j - 1]) {
307+
f[i][j] = f[i - 1][j - 1] + 1;
308+
ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i]));
309+
ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j]));
310+
}
311+
}
312+
}
313+
314+
return ans;
315+
}
119316
```
120317

121318
<!-- tabs:end -->

‎solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README_EN.md

+200-3
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3504.Lo
9595
#### Python3
9696

9797
```python
98-
98+
class Solution:
99+
def longestPalindrome(self, s: str, t: str) -> int:
100+
def expand(s: str, g: List[int], l: int, r: int):
101+
while l >= 0 and r < len(s) and s[l] == s[r]:
102+
g[l] = max(g[l], r - l + 1)
103+
l, r = l - 1, r + 1
104+
105+
def calc(s: str) -> List[int]:
106+
n = len(s)
107+
g = [0] * n
108+
for i in range(n):
109+
expand(s, g, i, i)
110+
expand(s, g, i, i + 1)
111+
return g
112+
113+
m, n = len(s), len(t)
114+
t = t[::-1]
115+
g1, g2 = calc(s), calc(t)
116+
ans = max(*g1, *g2)
117+
f = [[0] * (n + 1) for _ in range(m + 1)]
118+
for i, a in enumerate(s, 1):
119+
for j, b in enumerate(t, 1):
120+
if a == b:
121+
f[i][j] = f[i - 1][j - 1] + 1
122+
ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i]))
123+
ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j]))
124+
return ans
99125
```
100126

101127
#### Java
102128

103129
```java
104-
130+
class Solution {
131+
public int longestPalindrome(String S, String T) {
132+
char[] s = S.toCharArray();
133+
char[] t = new StringBuilder(T).reverse().toString().toCharArray();
134+
int m = s.length, n = t.length;
135+
int[] g1 = calc(s), g2 = calc(t);
136+
int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt());
137+
int[][] f = new int[m + 1][n + 1];
138+
for (int i = 1; i <= m; ++i) {
139+
for (int j = 1; j <= n; ++j) {
140+
if (s[i - 1] == t[j - 1]) {
141+
f[i][j] = f[i - 1][j - 1] + 1;
142+
ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
143+
ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
144+
}
145+
}
146+
}
147+
return ans;
148+
}
149+
150+
private void expand(char[] s, int[] g, int l, int r) {
151+
while (l >= 0 && r < s.length && s[l] == s[r]) {
152+
g[l] = Math.max(g[l], r - l + 1);
153+
--l;
154+
++r;
155+
}
156+
}
157+
158+
private int[] calc(char[] s) {
159+
int n = s.length;
160+
int[] g = new int[n];
161+
for (int i = 0; i < n; ++i) {
162+
expand(s, g, i, i);
163+
expand(s, g, i, i + 1);
164+
}
165+
return g;
166+
}
167+
}
105168
```
106169

107170
#### C++
108171

109172
```cpp
110-
173+
class Solution {
174+
public:
175+
int longestPalindrome(string s, string t) {
176+
int m = s.size(), n = t.size();
177+
ranges::reverse(t);
178+
vector<int> g1 = calc(s), g2 = calc(t);
179+
int ans = max(ranges::max(g1), ranges::max(g2));
180+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
181+
for (int i = 1; i <= m; ++i) {
182+
for (int j = 1; j <= n; ++j) {
183+
if (s[i - 1] == t[j - 1]) {
184+
f[i][j] = f[i - 1][j - 1] + 1;
185+
ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
186+
ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
187+
}
188+
}
189+
}
190+
return ans;
191+
}
192+
193+
private:
194+
void expand(const string& s, vector<int>& g, int l, int r) {
195+
while (l >= 0 && r < s.size() && s[l] == s[r]) {
196+
g[l] = max(g[l], r - l + 1);
197+
--l;
198+
++r;
199+
}
200+
}
201+
202+
vector<int> calc(const string& s) {
203+
int n = s.size();
204+
vector<int> g(n, 0);
205+
for (int i = 0; i < n; ++i) {
206+
expand(s, g, i, i);
207+
expand(s, g, i, i + 1);
208+
}
209+
return g;
210+
}
211+
};
111212
```
112213

113214
#### Go
114215

115216
```go
217+
func longestPalindrome(s, t string) int {
218+
m, n := len(s), len(t)
219+
t = reverse(t)
220+
221+
g1, g2 := calc(s), calc(t)
222+
ans := max(slices.Max(g1), slices.Max(g2))
223+
224+
f := make([][]int, m+1)
225+
for i := range f {
226+
f[i] = make([]int, n+1)
227+
}
228+
229+
for i := 1; i <= m; i++ {
230+
for j := 1; j <= n; j++ {
231+
if s[i-1] == t[j-1] {
232+
f[i][j] = f[i-1][j-1] + 1
233+
a, b := 0, 0
234+
if i < m {
235+
a = g1[i]
236+
}
237+
if j < n {
238+
b = g2[j]
239+
}
240+
ans = max(ans, f[i][j]*2+a)
241+
ans = max(ans, f[i][j]*2+b)
242+
}
243+
}
244+
}
245+
return ans
246+
}
247+
248+
func calc(s string) []int {
249+
n, g := len(s), make([]int, len(s))
250+
for i := 0; i < n; i++ {
251+
expand(s, g, i, i)
252+
expand(s, g, i, i+1)
253+
}
254+
return g
255+
}
256+
257+
func expand(s string, g []int, l, r int) {
258+
for l >= 0 && r < len(s) && s[l] == s[r] {
259+
g[l] = max(g[l], r-l+1)
260+
l, r = l-1, r+1
261+
}
262+
}
263+
264+
func reverse(s string) string {
265+
r := []rune(s)
266+
slices.Reverse(r)
267+
return string(r)
268+
}
269+
```
116270

271+
#### TypeScript
272+
273+
```ts
274+
function longestPalindrome(s: string, t: string): number {
275+
function expand(s: string, g: number[], l: number, r: number): void {
276+
while (l >= 0 && r < s.length && s[l] === s[r]) {
277+
g[l] = Math.max(g[l], r - l + 1);
278+
l--;
279+
r++;
280+
}
281+
}
282+
283+
function calc(s: string): number[] {
284+
const n = s.length;
285+
const g: number[] = Array(n).fill(0);
286+
for (let i = 0; i < n; i++) {
287+
expand(s, g, i, i);
288+
expand(s, g, i, i + 1);
289+
}
290+
return g;
291+
}
292+
293+
const m = s.length,
294+
n = t.length;
295+
t = t.split('').reverse().join('');
296+
const g1 = calc(s);
297+
const g2 = calc(t);
298+
let ans = Math.max(...g1, ...g2);
299+
300+
const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
301+
302+
for (let i = 1; i <= m; i++) {
303+
for (let j = 1; j <= n; j++) {
304+
if (s[i - 1] === t[j - 1]) {
305+
f[i][j] = f[i - 1][j - 1] + 1;
306+
ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i]));
307+
ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j]));
308+
}
309+
}
310+
}
311+
312+
return ans;
313+
}
117314
```
118315

119316
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
public:
3+
int longestPalindrome(string s, string t) {
4+
int m = s.size(), n = t.size();
5+
ranges::reverse(t);
6+
vector<int> g1 = calc(s), g2 = calc(t);
7+
int ans = max(ranges::max(g1), ranges::max(g2));
8+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
9+
for (int i = 1; i <= m; ++i) {
10+
for (int j = 1; j <= n; ++j) {
11+
if (s[i - 1] == t[j - 1]) {
12+
f[i][j] = f[i - 1][j - 1] + 1;
13+
ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
14+
ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
15+
}
16+
}
17+
}
18+
return ans;
19+
}
20+
21+
private:
22+
void expand(const string& s, vector<int>& g, int l, int r) {
23+
while (l >= 0 && r < s.size() && s[l] == s[r]) {
24+
g[l] = max(g[l], r - l + 1);
25+
--l;
26+
++r;
27+
}
28+
}
29+
30+
vector<int> calc(const string& s) {
31+
int n = s.size();
32+
vector<int> g(n, 0);
33+
for (int i = 0; i < n; ++i) {
34+
expand(s, g, i, i);
35+
expand(s, g, i, i + 1);
36+
}
37+
return g;
38+
}
39+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
func longestPalindrome(s, t string) int {
2+
m, n := len(s), len(t)
3+
t = reverse(t)
4+
5+
g1, g2 := calc(s), calc(t)
6+
ans := max(slices.Max(g1), slices.Max(g2))
7+
8+
f := make([][]int, m+1)
9+
for i := range f {
10+
f[i] = make([]int, n+1)
11+
}
12+
13+
for i := 1; i <= m; i++ {
14+
for j := 1; j <= n; j++ {
15+
if s[i-1] == t[j-1] {
16+
f[i][j] = f[i-1][j-1] + 1
17+
a, b := 0, 0
18+
if i < m {
19+
a = g1[i]
20+
}
21+
if j < n {
22+
b = g2[j]
23+
}
24+
ans = max(ans, f[i][j]*2+a)
25+
ans = max(ans, f[i][j]*2+b)
26+
}
27+
}
28+
}
29+
return ans
30+
}
31+
32+
func calc(s string) []int {
33+
n, g := len(s), make([]int, len(s))
34+
for i := 0; i < n; i++ {
35+
expand(s, g, i, i)
36+
expand(s, g, i, i+1)
37+
}
38+
return g
39+
}
40+
41+
func expand(s string, g []int, l, r int) {
42+
for l >= 0 && r < len(s) && s[l] == s[r] {
43+
g[l] = max(g[l], r-l+1)
44+
l, r = l-1, r+1
45+
}
46+
}
47+
48+
func reverse(s string) string {
49+
r := []rune(s)
50+
slices.Reverse(r)
51+
return string(r)
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution {
2+
public int longestPalindrome(String S, String T) {
3+
char[] s = S.toCharArray();
4+
char[] t = new StringBuilder(T).reverse().toString().toCharArray();
5+
int m = s.length, n = t.length;
6+
int[] g1 = calc(s), g2 = calc(t);
7+
int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt());
8+
int[][] f = new int[m + 1][n + 1];
9+
for (int i = 1; i <= m; ++i) {
10+
for (int j = 1; j <= n; ++j) {
11+
if (s[i - 1] == t[j - 1]) {
12+
f[i][j] = f[i - 1][j - 1] + 1;
13+
ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0));
14+
ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0));
15+
}
16+
}
17+
}
18+
return ans;
19+
}
20+
21+
private void expand(char[] s, int[] g, int l, int r) {
22+
while (l >= 0 && r < s.length && s[l] == s[r]) {
23+
g[l] = Math.max(g[l], r - l + 1);
24+
--l;
25+
++r;
26+
}
27+
}
28+
29+
private int[] calc(char[] s) {
30+
int n = s.length;
31+
int[] g = new int[n];
32+
for (int i = 0; i < n; ++i) {
33+
expand(s, g, i, i);
34+
expand(s, g, i, i + 1);
35+
}
36+
return g;
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution:
2+
def longestPalindrome(self, s: str, t: str) -> int:
3+
def expand(s: str, g: List[int], l: int, r: int):
4+
while l >= 0 and r < len(s) and s[l] == s[r]:
5+
g[l] = max(g[l], r - l + 1)
6+
l, r = l - 1, r + 1
7+
8+
def calc(s: str) -> List[int]:
9+
n = len(s)
10+
g = [0] * n
11+
for i in range(n):
12+
expand(s, g, i, i)
13+
expand(s, g, i, i + 1)
14+
return g
15+
16+
m, n = len(s), len(t)
17+
t = t[::-1]
18+
g1, g2 = calc(s), calc(t)
19+
ans = max(*g1, *g2)
20+
f = [[0] * (n + 1) for _ in range(m + 1)]
21+
for i, a in enumerate(s, 1):
22+
for j, b in enumerate(t, 1):
23+
if a == b:
24+
f[i][j] = f[i - 1][j - 1] + 1
25+
ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i]))
26+
ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j]))
27+
return ans
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
function longestPalindrome(s: string, t: string): number {
2+
function expand(s: string, g: number[], l: number, r: number): void {
3+
while (l >= 0 && r < s.length && s[l] === s[r]) {
4+
g[l] = Math.max(g[l], r - l + 1);
5+
l--;
6+
r++;
7+
}
8+
}
9+
10+
function calc(s: string): number[] {
11+
const n = s.length;
12+
const g: number[] = Array(n).fill(0);
13+
for (let i = 0; i < n; i++) {
14+
expand(s, g, i, i);
15+
expand(s, g, i, i + 1);
16+
}
17+
return g;
18+
}
19+
20+
const m = s.length,
21+
n = t.length;
22+
t = t.split('').reverse().join('');
23+
const g1 = calc(s);
24+
const g2 = calc(t);
25+
let ans = Math.max(...g1, ...g2);
26+
27+
const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
28+
29+
for (let i = 1; i <= m; i++) {
30+
for (let j = 1; j <= n; j++) {
31+
if (s[i - 1] === t[j - 1]) {
32+
f[i][j] = f[i - 1][j - 1] + 1;
33+
ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i]));
34+
ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j]));
35+
}
36+
}
37+
}
38+
39+
return ans;
40+
}

0 commit comments

Comments
 (0)
Please sign in to comment.