Skip to content

Commit 64c8837

Browse files
committed
feat: add solution 1960. Maximum Product of the Length of Two Palindromic Substrings
1 parent 2db66fe commit 64c8837

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# [1960. Maximum Product of the Length of Two Palindromic Substrings](https://leetcode.com/problems/maximum-product-of-the-length-of-two-palindromic-substrings)
2+
3+
## Description
4+
5+
<div class="elfjS" data-track-load="description_content"><p>You are given a <strong>0-indexed</strong> string <code>s</code> and are tasked with finding two <strong>non-intersecting palindromic </strong>substrings of <strong>odd</strong> length such that the product of their lengths is maximized.</p>
6+
7+
<p>More formally, you want to choose four integers <code>i</code>, <code>j</code>, <code>k</code>, <code>l</code> such that <code>0 &lt;= i &lt;= j &lt; k &lt;= l &lt; s.length</code> and both the substrings <code>s[i...j]</code> and <code>s[k...l]</code> are palindromes and have odd lengths. <code>s[i...j]</code> denotes a substring from index <code>i</code> to index <code>j</code> <strong>inclusive</strong>.</p>
8+
9+
<p>Return <em>the <strong>maximum</strong> possible product of the lengths of the two non-intersecting palindromic substrings.</em></p>
10+
11+
<p>A <strong>palindrome</strong> is a string that is the same forward and backward. A <strong>substring</strong> is a contiguous sequence of characters in a string.</p>
12+
13+
<p>&nbsp;</p>
14+
<p><strong class="example">Example 1:</strong></p>
15+
16+
<pre><strong>Input:</strong> s = "ababbb"
17+
<strong>Output:</strong> 9
18+
<strong>Explanation:</strong> Substrings "aba" and "bbb" are palindromes with odd length. product = 3 * 3 = 9.
19+
</pre>
20+
21+
<p><strong class="example">Example 2:</strong></p>
22+
23+
<pre><strong>Input:</strong> s = "zaaaxbbby"
24+
<strong>Output:</strong> 9
25+
<strong>Explanation:</strong> Substrings "aaa" and "bbb" are palindromes with odd length. product = 3 * 3 = 9.
26+
</pre>
27+
28+
<p>&nbsp;</p>
29+
<p><strong>Constraints:</strong></p>
30+
31+
<ul>
32+
<li><code>2 &lt;= s.length &lt;= 10<sup>5</sup></code></li>
33+
<li><code>s</code> consists of lowercase English letters.</li>
34+
</ul>
35+
</div>
36+
37+
<p>&nbsp;</p>
38+
39+
## Solutions
40+
41+
**Solution: `Manacher’s Algorithm`**
42+
43+
- Time complexity: <em>O(n)</em>
44+
- Space complexity: <em>O(n)</em>
45+
46+
<p>&nbsp;</p>
47+
48+
### **JavaScript**
49+
50+
```js
51+
/**
52+
* @param {string} s
53+
* @return {number}
54+
*/
55+
const maxProduct = function (s) {
56+
const n = s.length;
57+
58+
const manacher = str => {
59+
const maxExtends = Array.from({ length: n }, () => 0);
60+
const leftToRight = Array.from({ length: n }, () => 1);
61+
let center = 0;
62+
63+
for (let index = 0; index < n; index++) {
64+
const r = center + maxExtends[center] - 1;
65+
const mirrorIndex = center - (index - center);
66+
let extend = index > r ? 1 : Math.min(maxExtends[mirrorIndex], r - index + 1);
67+
68+
while (index - extend >= 0 && index + extend < n && str[index - extend] === str[index + extend]) {
69+
leftToRight[index + extend] = 2 * extend + 1;
70+
extend += 1;
71+
}
72+
73+
maxExtends[index] = extend;
74+
75+
if (index + maxExtends[index] >= r) {
76+
center = index;
77+
}
78+
}
79+
80+
for (let index = 1; index < n; index++) {
81+
leftToRight[index] = Math.max(leftToRight[index], leftToRight[index - 1]);
82+
}
83+
84+
return leftToRight;
85+
};
86+
87+
const maxLeft = manacher(s);
88+
const reversed = s.split('').reverse().join('');
89+
const maxRight = manacher(reversed).reverse();
90+
let reuslt = 1;
91+
92+
for (let index = 1; index < n; index++) {
93+
reuslt = Math.max(reuslt, maxLeft[index - 1] * maxRight[index]);
94+
}
95+
96+
return reuslt;
97+
};
98+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @param {string} s
3+
* @return {number}
4+
*/
5+
const maxProduct = function (s) {
6+
const n = s.length;
7+
8+
const manacher = str => {
9+
const maxExtends = Array.from({ length: n }, () => 0);
10+
const leftToRight = Array.from({ length: n }, () => 1);
11+
let center = 0;
12+
13+
for (let index = 0; index < n; index++) {
14+
const r = center + maxExtends[center] - 1;
15+
const mirrorIndex = center - (index - center);
16+
let extend = index > r ? 1 : Math.min(maxExtends[mirrorIndex], r - index + 1);
17+
18+
while (index - extend >= 0 && index + extend < n && str[index - extend] === str[index + extend]) {
19+
leftToRight[index + extend] = 2 * extend + 1;
20+
extend += 1;
21+
}
22+
23+
maxExtends[index] = extend;
24+
25+
if (index + maxExtends[index] >= r) {
26+
center = index;
27+
}
28+
}
29+
30+
for (let index = 1; index < n; index++) {
31+
leftToRight[index] = Math.max(leftToRight[index], leftToRight[index - 1]);
32+
}
33+
34+
return leftToRight;
35+
};
36+
37+
const maxLeft = manacher(s);
38+
const reversed = s.split('').reverse().join('');
39+
const maxRight = manacher(reversed).reverse();
40+
let reuslt = 1;
41+
42+
for (let index = 1; index < n; index++) {
43+
reuslt = Math.max(reuslt, maxLeft[index - 1] * maxRight[index]);
44+
}
45+
46+
return reuslt;
47+
};

0 commit comments

Comments
 (0)