Skip to content

Commit b8dec4a

Browse files
feat: add solutions to lc problem: No.1960
1 parent ed31865 commit b8dec4a

File tree

6 files changed

+601
-7
lines changed

6 files changed

+601
-7
lines changed

solution/1900-1999/1960.Maximum Product of the Length of Two Palindromic Substrings/README.md

Lines changed: 203 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/1900-1999/1960.Ma
55
rating: 2690
66
source: 第 58 场双周赛 Q4
77
tags:
8-
- 字符串
9-
- 哈希函数
10-
- 滚动哈希
8+
- 字符串
9+
- 哈希函数
10+
- 滚动哈希
1111
---
1212

1313
<!-- problem:start -->
@@ -69,28 +69,227 @@ tags:
6969

7070
```python
7171

72+
class Solution:
73+
def maxProduct(self, s: str) -> int:
74+
n = len(s)
75+
hlen = [0] * n
76+
center = right = 0
77+
78+
for i in range(n):
79+
if i < right:
80+
hlen[i] = min(right - i, hlen[2 * center - i])
81+
while (
82+
0 <= i - 1 - hlen[i]
83+
and i + 1 + hlen[i] < len(s)
84+
and s[i - 1 - hlen[i]] == s[i + 1 + hlen[i]]
85+
):
86+
hlen[i] += 1
87+
if right < i + hlen[i]:
88+
center, right = i, i + hlen[i]
89+
90+
prefix = [0] * n
91+
suffix = [0] * n
92+
93+
for i in range(n):
94+
prefix[i + hlen[i]] = max(prefix[i + hlen[i]], 2 * hlen[i] + 1)
95+
suffix[i - hlen[i]] = max(suffix[i - hlen[i]], 2 * hlen[i] + 1)
96+
97+
for i in range(1, n):
98+
prefix[~i] = max(prefix[~i], prefix[~i + 1] - 2)
99+
suffix[i] = max(suffix[i], suffix[i - 1] - 2)
100+
101+
for i in range(1, n):
102+
prefix[i] = max(prefix[i - 1], prefix[i])
103+
suffix[~i] = max(suffix[~i], suffix[~i + 1])
104+
105+
return max(prefix[i - 1] * suffix[i] for i in range(1, n))
106+
72107
```
73108

74109
#### Java
75110

76111
```java
77112

113+
class Solution {
114+
public long maxProduct(String s) {
115+
int n = s.length();
116+
if (n == 2) return 1;
117+
int[] len = manachers(s);
118+
long[] left = new long[n];
119+
int max = 1;
120+
left[0] = max;
121+
for (int i = 1; i <= n - 1; i++) {
122+
if (len[(i - max - 1 + i) / 2] > max) max += 2;
123+
left[i] = max;
124+
}
125+
max = 1;
126+
long[] right = new long[n];
127+
right[n - 1] = max;
128+
for (int i = n - 2; i >= 0; i--) {
129+
if (len[(i + max + 1 + i) / 2] > max) max += 2;
130+
right[i] = max;
131+
}
132+
long res = 1;
133+
for (int i = 1; i < n; i++) {
134+
res = Math.max(res, left[i - 1] * right[i]);
135+
}
136+
return res;
137+
}
138+
private int[] manachers(String s) {
139+
int len = s.length();
140+
int[] P = new int[len];
141+
int c = 0;
142+
int r = 0;
143+
for (int i = 0; i < len; i++) {
144+
int mirror = (2 * c) - i;
145+
if (i < r) {
146+
P[i] = Math.min(r - i, P[mirror]);
147+
}
148+
int a = i + (1 + P[i]);
149+
int b = i - (1 + P[i]);
150+
while (a < len && b >= 0 && s.charAt(a) == s.charAt(b)) {
151+
P[i]++;
152+
a++;
153+
b--;
154+
}
155+
if (i + P[i] > r) {
156+
c = i;
157+
r = i + P[i];
158+
}
159+
}
160+
for (int i = 0; i < len; i++) {
161+
P[i] = 1 + 2 * P[i];
162+
}
163+
return P;
164+
}
165+
}
166+
78167
```
79168

80169
#### C++
81170

82171
```cpp
83172

173+
class Solution {
174+
public:
175+
long long maxProduct(string s) {
176+
long long res = 0, l = 0, n = s.size();
177+
vector<int> m(n), r(n);
178+
179+
for (int i = 0, l = 0, r = -1; i < n; ++i) {
180+
int k = (i > r) ? 1 : min(m[l + r - i], r - i + 1);
181+
while (0 <= i - k && i + k < n && s[i - k] == s[i + k])
182+
k++;
183+
m[i] = k--;
184+
if (i + k > r) {
185+
l = i - k;
186+
r = i + k;
187+
}
188+
}
189+
190+
queue<array<int, 2>> q, q1;
191+
192+
for (int i = n - 1; i >= 0; --i) {
193+
while (!q.empty() && q.front()[0] - q.front()[1] > i - 1)
194+
q.pop();
195+
r[i] = 1 + (q.empty() ? 0 : (q.front()[0] - i) * 2);
196+
q.push({i, m[i]});
197+
}
198+
199+
for (int i = 0; i < n - 1; i++) {
200+
while (!q1.empty() && q1.front()[0] + q1.front()[1] < i + 1)
201+
q1.pop();
202+
l = max(l, 1ll + (q1.empty() ? 0 : (i - q1.front()[0]) * 2));
203+
res = max(res, l * r[i + 1]);
204+
q1.push({i, m[i]});
205+
}
206+
207+
return res;
208+
}
209+
};
210+
84211
```
85212

86213
#### Go
87214

88215
```go
89216

217+
func maxProduct(s string) int64 {
218+
n := len(s)
219+
hlen := make([]int, n)
220+
center, right := 0, 0
221+
222+
for i := 0; i < n; i++ {
223+
if i < right {
224+
mirror := 2*center - i
225+
if mirror >= 0 && mirror < n {
226+
hlen[i] = min(right-i, hlen[mirror])
227+
}
228+
}
229+
for i-1-hlen[i] >= 0 && i+1+hlen[i] < n && s[i-1-hlen[i]] == s[i+1+hlen[i]] {
230+
hlen[i]++
231+
}
232+
if i+hlen[i] > right {
233+
center = i
234+
right = i + hlen[i]
235+
}
236+
}
237+
238+
prefix := make([]int, n)
239+
suffix := make([]int, n)
240+
241+
for i := 0; i < n; i++ {
242+
r := i + hlen[i]
243+
if r < n {
244+
prefix[r] = max(prefix[r], 2*hlen[i]+1)
245+
}
246+
l := i - hlen[i]
247+
if l >= 0 {
248+
suffix[l] = max(suffix[l], 2*hlen[i]+1)
249+
}
250+
}
251+
252+
for i := 1; i < n; i++ {
253+
if n-i-1 >= 0 {
254+
prefix[n-i-1] = max(prefix[n-i-1], prefix[n-i]-2)
255+
}
256+
suffix[i] = max(suffix[i], suffix[i-1]-2)
257+
}
258+
259+
for i := 1; i < n; i++ {
260+
prefix[i] = max(prefix[i-1], prefix[i])
261+
suffix[n-i-1] = max(suffix[n-i], suffix[n-i-1])
262+
}
263+
264+
var res int64
265+
for i := 1; i < n; i++ {
266+
prod := int64(prefix[i-1]) * int64(suffix[i])
267+
if prod > res {
268+
res = prod
269+
}
270+
}
271+
272+
return res
273+
}
274+
275+
func max(a, b int) int {
276+
if a > b {
277+
return a
278+
}
279+
return b
280+
}
281+
282+
func min(a, b int) int {
283+
if a < b {
284+
return a
285+
}
286+
return b
287+
}
288+
90289
```
91290

92291
<!-- tabs:end -->
93292

94293
<!-- solution:end -->
95294

96-
<!-- problem:end -->
295+
<!-- problem:end -->

0 commit comments

Comments
 (0)