You are given a 0-indexed string s and are tasked with finding two
non-intersecting palindromic substrings of odd length such that the product of their lengths is maximized.
More formally, you want to choose four integers i, j, k, l such that
0 <= i <= j < k <= l < s.length and both the substrings s[i...j] and
s[k...l] are palindromes and have odd lengths. s[i...j] denotes a substring from index i to index jinclusive.
Return themaximum possible product of the lengths of the two non-intersecting palindromic substrings.
A palindrome is a string that is the same forward and backward. A
substring is a contiguous sequence of characters in a string.
To maximize the product of two non-overlapping odd-length palindromic substrings, we need to efficiently find the longest odd-length palindrome ending at or before each position (for the left substring) and starting at or after each position (for the right substring). Manacher’s algorithm allows us to find all palindromic substrings in linear time.
classSolution {
public:int maxProduct(string s) {
int n = s.size();
vector<int> d(n);
for (int i =0; i < n; ++i) {
int l =0;
while (i-l >=0&& i+l < n && s[i-l] == s[i+l]) ++l;
d[i] =2*l-1;
}
vector<int> pre(n), suf(n);
pre[0] = d[0];
for (int i =1; i < n; ++i) pre[i] = max(pre[i-1], d[i]);
suf[n-1] = d[n-1];
for (int i = n-2; i >=0; --i) suf[i] = max(suf[i+1], d[i]);
int ans =0;
for (int i =0; i < n-1; ++i) ans = max(ans, pre[i] * suf[i+1]);
return ans;
}
};
classSolution {
publicintmaxProduct(String s) {
int n = s.length();
int[] d =newint[n];
for (int i = 0; i < n; ++i) {
int l = 0;
while (i-l >= 0 && i+l < n && s.charAt(i-l) == s.charAt(i+l)) ++l;
d[i]= 2*l-1;
}
int[] pre =newint[n], suf =newint[n];
pre[0]= d[0];
for (int i = 1; i < n; ++i) pre[i]= Math.max(pre[i-1], d[i]);
suf[n-1]= d[n-1];
for (int i = n-2; i >= 0; --i) suf[i]= Math.max(suf[i+1], d[i]);
int ans = 0;
for (int i = 0; i < n-1; ++i) ans = Math.max(ans, pre[i]* suf[i+1]);
return ans;
}
}
classSolution {
funmaxProduct(s: String): Int {
val n = s.length
val d = IntArray(n)
for (i in0 until n) {
var l = 0while (i-l >=0&& i+l < n && s[i-l] == s[i+l]) l++ d[i] = 2*l-1 }
val pre = IntArray(n)
val suf = IntArray(n)
pre[0] = d[0]
for (i in1 until n) pre[i] = maxOf(pre[i-1], d[i])
suf[n-1] = d[n-1]
for (i in n-2 downTo 0) suf[i] = maxOf(suf[i+1], d[i])
var ans = 0for (i in0 until n-1) ans = maxOf(ans, pre[i] * suf[i+1])
return ans
}
}
classSolution:
defmaxProduct(self, s: str) -> int:
n = len(s)
d = [0] * n
for i in range(n):
l =0while i-l >=0and i+l < n and s[i-l] == s[i+l]:
l +=1 d[i] =2*l-1 pre = [0] * n
suf = [0] * n
pre[0] = d[0]
for i in range(1, n):
pre[i] = max(pre[i-1], d[i])
suf[-1] = d[-1]
for i in range(n-2, -1, -1):
suf[i] = max(suf[i+1], d[i])
ans =0for i in range(n-1):
ans = max(ans, pre[i] * suf[i+1])
return ans
impl Solution {
pubfnmax_product(s: String) -> i32 {
let n = s.len();
let s = s.as_bytes();
letmut d =vec![0; n];
for i in0..n {
letmut l =0;
while i asi32- l >=0&& i + l < n && s[i-l] == s[i+l] {
l +=1;
}
d[i] =2*l-1;
}
letmut pre =vec![0; n];
letmut suf =vec![0; n];
pre[0] = d[0];
for i in1..n {
pre[i] = pre[i-1].max(d[i]);
}
suf[n-1] = d[n-1];
for i in (0..n-1).rev() {
suf[i] = suf[i+1].max(d[i]);
}
letmut ans =0;
for i in0..n-1 {
ans = ans.max(pre[i] * suf[i+1]);
}
ans
}
}