Valid Palindrome

Check if a string reads the same forward and backward after lowercasing and dropping non-alphanumerics.

Easy
Time O(n) Space O(1)
LeetCode
3 min read
two-pointers string

Problem#

Return true if, after lowercasing and removing all non-alphanumeric characters, the string equals its reverse.

Examples#

  • "A man, a plan, a canal: Panama"true (becomes "amanaplanacanalpanama")
  • "race a car"false ("raceacar")
  • " "true (empty)

Constraints#

  • 1 <= s.length <= 2 * 10^5, ASCII.

Hints#

Hint 1
Skip junk characters in-place rather than building a cleaned copy.
Hint 2
Two pointers walking inward; compare lowercased letters/digits only.

Approach#

Filter then compare — O(n) space for the cleaned string.
Two pointers in place — advance each pointer past non-alphanumerics, then compare. O(1) space.

Solution#

Valid Palindrome
class Solution {
public:
bool isPalindrome(string s) {
int l = 0, r = s.size() - 1;
while (l < r) {
while (l < r && !isalnum((unsigned char)s[l])) ++l;
while (l < r && !isalnum((unsigned char)s[r])) --r;
if (tolower((unsigned char)s[l]) != tolower((unsigned char)s[r])) return false;
++l; --r;
}
return true;
}
};

Editorial#

Both pointers are responsible for their own skip logic — that keeps the comparison branch simple. Casting to unsigned char before isalnum/tolower avoids undefined behavior on signed-char platforms when the input contains bytes ≥ 0x80. The l < r guard in the inner skips protects against a string that is entirely punctuation (we’d otherwise walk off the ends).

Complexity#

  • Time: O(n) — each index advances at most once.
  • Space: O(1).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.