1
// using manachers algorithm5
public long maxProduct(String s) {8
int[] len = manachers(s); // get lengths of palindromes at each element10
long left[] = new long[n]; // stores the max length of palindrome to left of each index14
for (int i = 1; i <= n - 1; i++) {15
// does any palindrome end at i with length greater than max16
if (len[(i - max - 1 + i) / 2] > max) max += 2;20
long[] right = new long[n]; // stores the max length of palindrome to right of each index23
for (int i = n - 2; i >= 0; i--) {24
// does any palindrome start at i with length greater than max25
if (len[(i + max + 1 + i) / 2] > max) max += 2;31
for (int i = 1; i < n; i++) {32
res = Math.max(res, left[i - 1] * right[i]);38
// https://hackernoon.com/manachers-algorithm-explained-longest-palindromic-substring-22cb27a5e96f39
private int[] manachers(String s) {42
int[] P = new int[len];43
int c = 0; // stores the center of the longest palindromic substring until now44
int r = 0; // stores the right boundary of the longest palindromic substring until now47
for (int i = 0; i < len; i++) {48
// get mirror index of i49
int mirror = (2 * c) - i;51
// see if the mirror of i is expanding beyond the left boundary of current longest palindrome53
// if it is, then take r - i as P[i]54
// else take P[mirror] as P[i]56
P[i] = Math.min(r - i, P[mirror]);60
int a = i + (1 + P[i]);61
int b = i - (1 + P[i]);62
while (a < len && b >= 0 && s.charAt(a) == s.charAt(b)) {68
// check if the expanded palindrome at i is expanding beyond the right boundary of current69
// longest palindrome at center c70
// if it is, the new center is i76
for (int i = 0; i < len; i++) P[i] = 1 + 2 * P[i];