~20 minutes · Day 13 · strings · Python
Today's interview problem is Longest Palindromic Substring. It sounds like a search problem: somewhere inside the string is the longest piece that reads the same forward and backward. The tempting move is to inspect every substring. The interview move is to notice that every possible answer must grow from a center.
Every palindrome has a center; there are 2n-1 centers, so expand outward from each.
A palindrome is symmetric: the left and right characters match as you walk inward. That symmetry gives you permission to walk the other direction. Pick a center, compare the two sides, and expand while they match.
Each expansion asks one question: do the characters one step farther out still match?
The brute force approach is O(n³): choose every substring in O(n²), then check whether each one is a palindrome in O(n). It works, but it keeps rediscovering the same symmetry from scratch.
The center approach asks a smaller question: if this index, or this gap between indices, is the middle, how far can the palindrome grow?
def longest_palindrome(s):
best_l = best_r = 0
for c in range(len(s)):
for l, r in ((c, c), (c, c + 1)): # odd center, even center
while l >= 0 and r < len(s) and s[l] == s[r]:
if r - l > best_r - best_l:
best_l, best_r = l, r # longest seen so far
l -= 1 # expand left
r += 1 # expand right
return s[best_l:best_r + 1]
There are two center shapes. An odd-length palindrome has a real character in the middle, like racecar. An even-length palindrome has a gap in the middle, like abba. For a string of length n, that is n character centers plus n - 1 gap centers: 2n - 1 total.
The loop checks a character center for odd palindromes and the next gap for even palindromes.
Palindromic Substrings: instead of returning the longest palindrome, count how many palindromic substrings exist.
Before opening the reveal: keep the same centers. What changes inside the expansion loop?
def count_substrings(s):
count = 0
for c in range(len(s)):
for l, r in ((c, c), (c, c + 1)):
while l >= 0 and r < len(s) and s[l] == s[r]:
count += 1 # every valid expansion is one palindrome
l -= 1
r += 1
return count
Same invariant, different payload. Longest Palindromic Substring updates the best range. Palindromic Substrings increments a count for every successful expansion.
| Approach | Time | Space |
|---|---|---|
| Brute force (check every substring) | O(n³) | O(1) |
| Expand around center | O(n²) | O(1) |
Aside from the returned substring, the space stays constant because the algorithm only carries two best indices and the current left/right pointers. The speed improves because each center expands directly until symmetry breaks.
1. How many centers can a non-empty string have?
n character centers for odd palindromes and n - 1 gap centers for even palindromes, so the total is 2n - 1.2. Spot the bug in this expansion guard: while l > 0 and r < len(s).
0. The guard must be l >= 0, otherwise a palindrome that reaches the first character gets cut off.3. Which problem shape points to expand around center?
4. Why do we expand from (c, c + 1)?
(c, c) handles a character center. (c, c + 1) handles the gap between two characters, which is where even-length palindromes grow.Solve Longest Palindromic Substring in your Notion tracker using the cycle — predict → attempt → compare → encode:
Watch NeetCode — Longest Palindromic Substring after your attempt, as the compare step. Listen for how he separates odd centers from even centers.