Jump to section
The longest palindromic substring problem asks for the longest contiguous part of a string that reads the same forwards and backwards. The standard interview answer is expand around centre: try every character and every gap between two characters as a centre and grow outwards. It runs in O(n²) time and O(1) extra space.
The Problem
You are given a string s. Return the longest substring of s that is a palindrome, meaning it reads the same from left to right as from right to left. A substring has to be contiguous: you cannot skip characters.
Example 1
Input: "bananas". Output: "anana". The five characters mirror each other around the middle n, and nothing longer does.
Example 2
Input: "noonday". Output: "noon". This palindrome has an even length, so its centre sits between the two o characters rather than on one of them. That detail is the trap in this question.
Assumptions to confirm
- If two palindromes tie for longest, can you return either? Usually yes.
- Is the input case-sensitive, and can it contain spaces or punctuation? Assume yes and compare characters exactly unless told otherwise.
- What should an empty string return? An empty string is the natural answer.
Brute Force First
The naive approach checks every substring. There are about n²/2 substrings, and checking whether each one is a palindrome takes up to O(n), so the total is O(n³) time. It works for short strings and it is easy to explain, which is exactly why you should say it out loud before optimising.
Interviewers want to hear the brute force because it shows you understand the problem fully and gives you a baseline to improve on. Spend thirty seconds on it, give its complexity, then explain where the waste is: you keep re-checking characters you have already compared.
Ready to put this into practice?
Practice this with MockIF →Still applying for jobs? Let Auto Apply do it
The Optimal Approach: Expand Around Centre
Notice that every palindrome has a centre
An odd-length palindrome is centred on one character, an even-length one on the gap between two characters. A string of length n has 2n − 1 possible centres.
Expand from each centre
Start with left and right pointers at the centre and move them outwards while the characters match. When they stop matching, the last matching window is the longest palindrome at that centre.
Check both kinds of centre
For each index i, expand from (i, i) for odd lengths and from (i, i + 1) for even lengths. Forgetting the even case is the most common bug.
Keep the best window
Track the start and length of the longest palindrome seen so far, and slice it out at the end instead of building strings inside the loop.
Python and TypeScript Solutions
Python
def longest_palindrome(s: str) -> str:
if len(s) < 2:
return s
start, best_len = 0, 1
def expand(left: int, right: int) -> None:
nonlocal start, best_len
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
length = right - left - 1
if length > best_len:
start, best_len = left + 1, length
for i in range(len(s)):
expand(i, i) # odd length, centred on s[i]
expand(i, i + 1) # even length, centred between s[i] and s[i+1]
return s[start:start + best_len]
TypeScript
function longestPalindrome(s: string): string {
if (s.length < 2) return s;
let start = 0;
let bestLen = 1;
const expand = (left: number, right: number): void => {
while (left >= 0 && right < s.length && s[left] === s[right]) {
left--;
right++;
}
const length = right - left - 1;
if (length > bestLen) {
start = left + 1;
bestLen = length;
}
};
for (let i = 0; i < s.length; i++) {
expand(i, i); // odd length, centred on s[i]
expand(i, i + 1); // even length, centred between s[i] and s[i + 1]
}
return s.slice(start, start + bestLen);
}
Both versions store only a start index and a length, so the string is sliced once at the end. Expanding a centre stops as soon as characters differ, which is why the average case is much faster than the worst case.
Ready to put this into practice?
Practice this with MockIF →Still applying for jobs? Let Auto Apply do it
Complexity Compared
| Approach | Time | Extra space | When to mention it |
|---|---|---|---|
| Brute force | O(n³) | O(1) | First, as the baseline |
| Dynamic programming table | O(n²) | O(n²) | As an alternative if asked |
| Expand around centre | O(n²) | O(1) | The answer to code |
| Manacher's algorithm | O(n) | O(n) | Only as a follow-up; rarely expected to be coded |
How to Talk Through It in an Interview
A short script you can adapt:
- Clarify: "So I return the substring itself, not its length, and any of several tied answers is fine?"
- Brute force: "I could check every substring, which is O(n³). The waste is re-comparing the same characters."
- Optimise: "Every palindrome mirrors around a centre, and there are 2n − 1 centres including the gaps. If I expand from each one, I get O(n²) time with constant space."
- Code: write the helper that expands, then the loop that calls it twice per index. Say why you track start and length instead of strings.
- Test: walk through "abba" to show the even centre works, then "a" and the empty string.
Ready to put this into practice?
Practice this with MockIF →Still applying for jobs? Let Auto Apply do it
Edge Cases and Follow-Ups
Even-length palindromes
"abba" and "aaaa" have no single middle character. If your code only expands from (i, i), these fail.
Very short input
Empty strings and single characters are already palindromes. Return them straight away.
Follow-up: count palindromic substrings
The same expansion works. Add one to a counter every time the window grows instead of tracking the longest.
Follow-up: can you do it in linear time?
Mention Manacher's algorithm, which reuses information from mirrored centres to reach O(n). Interviewers usually want you to know it exists rather than code it.
Follow-up: longest palindromic subsequence
A subsequence can skip characters, so it needs a different dynamic programming solution. Point out the difference before you answer.
Practise It in a Mock Coding Round
Reading a solution is not the same as producing it with someone watching. In a real round you have to clarify the problem, say the brute force out loud, and keep talking while you type. MockIF runs coding rounds with a voice AI interviewer in a real in-browser editor, in Python and TypeScript. It runs your code against tests, asks you to explain your approach, follows up on edge cases and complexity, then scores the round and gives you specific feedback. A session costs 2 credits. It is free to start with 5 credits, then monthly or 3-monthly plans, or one-off credit packs (see pricing). Read more about how a mock coding interview works.
Frequently Asked Questions
What is the best approach for longest palindromic substring?
Why are there 2n − 1 centres?
Is dynamic programming better than expand around centre?
Do I need to know Manacher's algorithm?
What is the difference between a palindromic substring and subsequence?
Stop Preparing in Your Head. Start Practicing Out Loud.
Drop your resume, add a job description, and get a mock interview like the real thing.
Start Free Mock Interview →Still applying for jobs? Let Auto Apply do it for you.