17. Valid Palindrome
easyAsked at VercelDecide whether a string is a palindrome after normalizing (lowercase + remove non-alphanumeric). Vercel asks this to test string-handling fluency plus the two-pointer in-place sweep — same pattern as their URL-segment normalizer.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Vercel loops.
- Glassdoor (2025-Q4)— Vercel screen; two-pointer expected over the regex shortcut.
- LeetCode Discuss (2026-Q1)— Mentioned in Vercel onsite recap.
Problem
A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Given a string s, return true if it is a palindrome, or false otherwise.
Constraints
1 <= s.length <= 2 * 10^5s consists only of printable ASCII characters.
Examples
Example 1
s = "A man, a plan, a canal: Panama"trueExample 2
s = "race a car"falseExample 3
s = " "trueExplanation: After cleanup the string is empty, which is a palindrome.
Approaches
1. Clean then reverse-compare
Lowercase, strip non-alphanumeric, then check str === str.reverse().
- Time
- O(n)
- Space
- O(n)
function isPalindrome(s) {
const cleaned = s.toLowerCase().replace(/[^a-z0-9]/g, '');
return cleaned === cleaned.split('').reverse().join('');
}Tradeoff: Works but allocates three intermediate strings. Mention as the obvious starting point, then pivot.
2. Two-pointer with in-place skip (optimal)
Pointers from both ends. Skip non-alphanumerics on each side, then compare lowercased characters.
- Time
- O(n)
- Space
- O(1)
function isPalindrome(s) {
const isAlnum = (c) => /[a-z0-9]/i.test(c);
let i = 0, j = s.length - 1;
while (i < j) {
while (i < j && !isAlnum(s[i])) i++;
while (i < j && !isAlnum(s[j])) j--;
if (s[i].toLowerCase() !== s[j].toLowerCase()) return false;
i++; j--;
}
return true;
}Tradeoff: O(1) extra space. The two inner whiles must check i < j to avoid infinite loops when the string is all-punctuation.
Vercel-specific tips
Vercel grades for the two-pointer with in-place character skipping. Bonus signal: explicitly handling the all-punctuation case (the inner whiles need the i < j guard). Avoid the regex shortcut unless the interviewer allows it — they want the manual skip logic.
Common mistakes
- Forgetting i < j in the inner whiles — infinite loop on inputs like ',,,'.
- Using charCodeAt to test alphanumeric and getting the ranges wrong — verify '0'-'9', 'a'-'z', 'A'-'Z' all included.
- Mutating the string with replace inside the loop — strings are immutable in JS, so every replace allocates.
Follow-up questions
An interviewer at Vercel may pivot to one of these next:
- Allow removing at most one character (LC 680).
- Find the longest palindromic substring (LC 5).
- Valid palindrome with custom alphabet (e.g., ignore digits).
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why two pointers and not reverse-compare?
Reverse-compare allocates a second string. Two-pointer is O(1) space and exits early on the first mismatch — both wins.
What about Unicode?
ASCII-only by constraint. For Unicode, normalize with String.normalize('NFD') and a Unicode-aware regex; flag the interviewer that this gets significantly harder.
Practice these live with InterviewChamp.AI
Drill Valid Palindrome and other Vercel interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →