Valid Palindrome
Alphanumeric palindrome check — two pointers skipping non-alphanumerics, O(n) time O(1) space.
beginner3 min read
- dsa
- strings
- interview
- Meta
- Amazon
The problem
After converting to lowercase and removing non-alphanumeric characters, does s read the same forward and backward?
Input: s = "A man, a plan, a canal: Panama"
Output: true
Input: s = "race a car"
Output: false
Input: s = " "
Output: true
Brute force
Filter + reverse string compare.
function isPalindromeBrute(s: string): boolean {
const cleaned = s.toLowerCase().replace(/[^a-z0-9]/g, "");
return cleaned === [...cleaned].reverse().join("");
}
| Time | O(n) |
| Space | O(n) |
Optimal: two pointers
function isPalindrome(s: string): boolean {
let lo = 0;
let hi = s.length - 1;
const isAlnum = (ch: string) => /[a-z0-9]/i.test(ch);
while (lo < hi) {
while (lo < hi && !isAlnum(s[lo])) lo++;
while (lo < hi && !isAlnum(s[hi])) hi--;
if (s[lo].toLowerCase() !== s[hi].toLowerCase()) return false;
lo++;
hi--;
}
return true;
}
Char-code version of alnum avoids regex if you prefer:
function isAlnumCode(ch: string): boolean {
const c = ch.charCodeAt(0);
return (
(c >= 48 && c <= 57) ||
(c >= 65 && c <= 90) ||
(c >= 97 && c <= 122)
);
}
| Time | O(n) |
| Space | O(1) |
Edge cases
- Empty / only punctuation → true
- Single character
- Numbers mixed with letters
- Unicode letters — LC usually ASCII
Common bugs
- Forgetting to lowercase
- Treating underscore as alnum
- Moving lo/hi past each other incorrectly
- Off-by-one when skipping
Interview delivery
- Define cleaned palindrome.
- Two pointers skip junk.
- Compare lowercased.
- O(n)/O(1).
- Follow-up: valid palindrome II (one delete).
Related
Walkthrough
s = "A man, a plan, a canal: Panama"
- lo at
'A', hi at'a'— both alnum, equal ignoring case - skip spaces and punctuation as pointers move inward
- eventually all letter pairs match → true
s = "race a car"
- after clean mentally:
raceacar 'r'vs'r'ok, … middle fails on'e'vs'a'→ false
Why not always filter first?
Filtering builds a new string (clear code, O(n) space). Two pointers keep O(1) space and show you control index movement — the skill they reuse on linked-list and array problems. If the language makes toLowerCase allocate per char, mention that cost is still O(n) total characters examined.
Related palindrome variants
- Valid Palindrome II — allow one deletion; branch when mismatch.
- Palindrome Linked List — reverse second half, compare.
- Longest Palindromic Substring — expand around centers.
Name one of these if they ask “what next?” after you finish early.