Leetcode #5
This one took way too long for some reason. My solution is a two pointer approach, but the ideal solution actually utilises Manacher’s Algorithm , which is used specifically for this problem - to find all palindromic substrings of a string in O(n) time.
I also took an incredible picture while working on this problem yesterday evening.

Problem
Given a string s, return the longest palindromic substring in s.
Example 1:
Input: s = “babad”
Output: “bab”
Explanation: “aba” is also a valid answer.
Example 2:
Input: s = “cbbd”
Output: “bb”
Constraints:
1 ⇐ s.length ⇐ 1000
s consist of only digits and English letters.
My Two Pointer Solution:
class Solution {
public String longestPalindrome(String s) {
/*
- iterate through each char c in s
- odd length palindrome:
- set this as middle
- left and right idx -1 +1 respectively
- if left == right: continue
- if s.charAt(i) == s.charAt(i+1) -> even length
- expand left and right from around this pair
*/
int len = s.length();
if (len == 1) {
return s;
}
int bestLeft = 0;
int bestLen = 1;
for (int i=0; i<len; i++) {
// odd length palindrome
int left = i-1;
int right = i+1;
while (left>=0 && right<len && s.charAt(left) == s.charAt(right)) {
int curLen = right-left+1;
if (curLen > bestLen) {
bestLen = curLen;
bestLeft = left;
}
left--;
right++;
}
// even length palindrome
left = i;
right = i+1;
while (left>=0 && right<len && s.charAt(left) == s.charAt(right)) {
int curLen = right-left+1;
if (curLen > bestLen) {
bestLen = curLen;
bestLeft = left;
}
left--;
right++;
}
}
return s.substring(bestLeft,bestLeft+bestLen);
}
}Manacher’s Algorithm Solution
public class Solution {
public int[] manacher(String s) {
StringBuilder t = new StringBuilder("#");
for (char c : s.toCharArray()) {
t.append(c).append("#");
}
int n = t.length();
int[] p = new int[n];
int l = 0, r = 0;
for (int i = 0; i < n; i++) {
p[i] = (i < r) ? Math.min(r - i, p[l + (r - i)]) : 0;
while (i + p[i] + 1 < n && i - p[i] - 1 >= 0 &&
t.charAt(i + p[i] + 1) == t.charAt(i - p[i] - 1)) {
p[i]++;
}
if (i + p[i] > r) {
l = i - p[i];
r = i + p[i];
}
}
return p;
}
public String longestPalindrome(String s) {
int[] p = manacher(s);
int resLen = 0, center_idx = 0;
for (int i = 0; i < p.length; i++) {
if (p[i] > resLen) {
resLen = p[i];
center_idx = i;
}
}
int resIdx = (center_idx - resLen) / 2;
return s.substring(resIdx, resIdx + resLen);
}
}