Longest Palindromic Substring
Longest palindromic substring — expand around centers O(n²), DP table alternative, and Manacher mention for O(n).
intermediate3 min read
- dsa
- dp
- interview
- Meta
- Amazon
- Microsoft
The problem
Return the longest palindromic substring of s. Any one is fine if ties.
"babad" → "bab" or "aba"
"cbbd" → "bb"
Brute
Check every s[i..j] for palindrome. O(n³) or O(n²) with better checks.
function longestPalindromeBrute(s: string): string {
let best = "";
for (let i = 0; i < s.length; i++) {
for (let j = i; j < s.length; j++) {
if (j - i + 1 > best.length && isPal(s, i, j)) best = s.slice(i, j + 1);
}
}
return best;
}
function isPal(s: string, i: number, j: number): boolean {
while (i < j) {
if (s[i] !== s[j]) return false;
i++;
j--;
}
return true;
}
| Time | O(n³) |
| Space | O(1) |
Expand around centers (preferred)
Every palindrome mirrors around a center. Centers are each index (odd length) and each gap between indices (even length). Expand while characters match.
function longestPalindrome(s: string): string {
if (!s) return "";
let start = 0;
let end = 0;
const expand = (l: number, r: number) => {
while (l >= 0 && r < s.length && s[l] === s[r]) {
l--;
r++;
}
// after fail, window is (l+1)..(r-1)
if (r - l - 1 > end - start + 1) {
start = l + 1;
end = r - 1;
}
};
for (let i = 0; i < s.length; i++) {
expand(i, i); // odd
expand(i, i + 1); // even
}
return s.slice(start, end + 1);
}
| Time | O(n²) |
| Space | O(1) |
Walk "cbbd"
Centers… at gap between two bs expand → "bb", longest.
DP table (also O(n²))
dp[i][j] = true if s[i..j] palindrome.
dp[i][j] = (s[i]===s[j]) && (j-i<2 || dp[i+1][j-1]).
function longestPalindromeDp(s: string): string {
const n = s.length;
if (n < 2) return s;
const dp: boolean[][] = Array.from({ length: n }, () => Array(n).fill(false));
let start = 0;
let maxLen = 1;
for (let i = 0; i < n; i++) dp[i][i] = true;
for (let len = 2; len <= n; len++) {
for (let i = 0; i + len - 1 < n; i++) {
const j = i + len - 1;
if (s[i] === s[j] && (len === 2 || dp[i + 1][j - 1])) {
dp[i][j] = true;
if (len > maxLen) {
maxLen = len;
start = i;
}
}
}
}
return s.slice(start, start + maxLen);
}
| Time | O(n²) |
| Space | O(n²) |
Manacher’s algorithm
True O(n) with transformed string and radius array. Rarely required; name it if they ask for better than n².
Edge cases
- Empty / single char
- Entire string palindrome
- All same characters
- Even vs odd lengths
Common mistakes
- Only expanding odd centers (miss
"bb") - Returning length instead of substring
- Off-by-one after expand loop
Interview delivery
- Substring not subsequence.
- Expand centers O(n²)/O(1).
- Code both odd and even.
- Mention DP / Manacher.
- Trace even case.
Related
- Valid Palindrome
- Longest Substring Without Repeating
- Palindrome Partitioning
- Longest Repeating Character Replacement
- JavaScript Interview Guide