125. Valid Palindrome
easyAsked at BloombergGiven a string, determine if it's a palindrome after removing non-alphanumeric characters and ignoring case. Bloomberg uses this to test two-pointer fluency plus a careful handling of mixed-content strings.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Bloomberg loops.
- Glassdoor (2026-Q1)— Bloomberg phone-screen reports cite Valid Palindrome as a recurring string + two-pointer warm-up.
- Blind (2025-11)— Bloomberg SWE new-grad reports list this among the most common Round 1 questions.
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. Alphanumeric characters include letters and numbers. 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"trueExplanation: "amanaplanacanalpanama" is a palindrome.
Example 2
s = "race a car"falseExplanation: "raceacar" is not a palindrome.
Example 3
s = " "trueExplanation: After removing non-alphanumeric chars, s = "" which is a palindrome.
Approaches
1. Two-pointer with in-place skip (optimal)
Two pointers from both ends. Skip non-alphanumeric on each side; compare lowercased characters.
- Time
- O(n)
- Space
- O(1)
function isPalindrome(s) {
const isAlnum = (ch) => /[a-z0-9]/i.test(ch);
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: Bloomberg's preferred answer. O(1) extra space — no string allocation. The inner while-loops handle skipping cleanly.
2. Filter then compare reverse
Build a cleaned lowercased string, compare to its reverse.
- Time
- O(n)
- Space
- O(n)
function isPalindromeFilter(s) {
const cleaned = s.toLowerCase().replace(/[^a-z0-9]/g, '');
return cleaned === cleaned.split('').reverse().join('');
}Tradeoff: Concise but O(n) extra space. Mention as the 'simple version' then offer the two-pointer for the production answer.
Bloomberg-specific tips
Bloomberg interviewers grade specifically on the IN-PLACE two-pointer — they want O(1) extra space. State 'I'll use two pointers from both ends and skip non-alphanumeric characters' before coding.
Common mistakes
- Forgetting that 'alphanumeric' includes digits, not just letters.
- Off-by-one when skipping (i < j must be re-checked inside the inner while-loops).
- Mishandling unicode or assuming only English letters — read the constraints (ASCII).
Follow-up questions
An interviewer at Bloomberg may pivot to one of these next:
- Valid Palindrome II (LC 680) — allow deleting at most one character.
- Longest Palindromic Substring (LC 5) — expand around center.
- Palindrome Linked List (LC 234) — reverse second half then compare.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why not just filter then reverse?
The filter+reverse version allocates O(n) extra. Two-pointer is O(1) and Bloomberg's rubric explicitly grades for it. Both pass on correctness.
Should I use regex inside the loop?
On a per-char check, regex is fine but slower than a direct character-range check. Either is acceptable in interview; mention the tradeoff if asked.
Free learning resources
Curated free links for this problem.
Practice these live with InterviewChamp.AI
Drill Valid Palindrome and other Bloomberg interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →