18. Valid Palindrome
easyAsked at RedditDetermine if a string is a palindrome after removing non-alphanumeric characters and lowercasing. Reddit uses this to test two-pointer technique on dirty input — exactly the kind of normalization their username/subreddit-name validation must handle.
By Sam K., Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Reddit loops.
- Glassdoor (2026-Q1)— Reddit phone screen, used to gauge string-handling carefulness.
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"trueExample 2
s = "race a car"falseExample 3
s = " "trueApproaches
1. Normalize then compare to reverse
Filter to alphanumeric, lowercase, compare to its reverse.
- Time
- O(n)
- Space
- O(n)
function isPalindrome(s) {
const t = s.toLowerCase().replace(/[^a-z0-9]/g, '');
return t === t.split('').reverse().join('');
}Tradeoff: Linear but allocates two copies. Acceptable as a first version but not interview-grade.
2. Two pointers, skip non-alnum in-place (optimal)
Pointers from both ends. Skip non-alphanumeric. Compare lowercased characters.
- Time
- O(n)
- Space
- O(1)
function isPalindrome(s) {
const isAlnum = (c) => /[a-z0-9]/.test(c);
let i = 0, j = s.length - 1;
while (i < j) {
while (i < j && !isAlnum(s[i].toLowerCase())) i++;
while (i < j && !isAlnum(s[j].toLowerCase())) j--;
if (s[i].toLowerCase() !== s[j].toLowerCase()) return false;
i++; j--;
}
return true;
}Tradeoff: O(1) memory. The skip-in-place is a recurring Reddit pattern for handling dirty user-input (usernames, comment text).
Reddit-specific tips
Reddit interviewers grade on whether you handle the i < j guard inside the inner while loops. Without it, you'll skip past j and crash. Bonus signal: relate this to their input-sanitization for username comparison (case-insensitive, ignore punctuation).
Common mistakes
- Forgetting i < j in inner skip loops — leads to out-of-bounds.
- Lowercasing only one side (must compare lowercased to lowercased).
- Using a regex per character — slow; pre-bind the test function.
Follow-up questions
An interviewer at Reddit may pivot to one of these next:
- Valid palindrome II (LC 680) — allow one deletion.
- Longest palindromic substring (LC 5).
- What if you couldn't use regex?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Does the empty string count?
Yes — empty reads the same forward and backward. The example with a single space confirms this.
Are accented characters alphanumeric?
Per the spec, only ASCII letters and digits. Constraints guarantee printable ASCII only, so this won't bite.