AlgoMaster Logo

Valid Palindrome

easyFrequencyUpdated August 19, 2026

Understanding the Problem

This is more than a plain "is this string a palindrome?" check. The problem adds two preprocessing rules: ignore case and ignore non-alphanumeric characters. The string "A man, a plan, a canal: Panama" has spaces, commas, and a colon, but after removing those characters and lowercasing the rest, it becomes "amanaplanacanalpanama", which reads the same forwards and backwards.

The two approaches below differ on one decision: whether to build the cleaned-up string explicitly, or skip the ignored characters while comparing.

Key Constraints:

  • 1 <= s.length <= 2 * 10^5 → With up to 200,000 characters, the solution needs to run in O(n) time. Both approaches do; they differ in space usage.
  • s consists only of printable ASCII characters → The input can contain letters, digits, spaces, punctuation, and symbols, but no Unicode characters. This means a single byte per character and a fixed test for "alphanumeric".

Approach 1: Filter and Reverse

Intuition

Do exactly what the problem describes: remove everything that isn't a letter or digit, convert the rest to lowercase, and check whether the result is a palindrome.

To check whether a string is a palindrome, compare it against its reverse. If the cleaned string equals its reverse, it is a palindrome.

Algorithm

  1. Iterate through every character in the input string.
  2. Keep only alphanumeric characters, converting each to lowercase.
  3. Build a new "cleaned" string from these characters.
  4. Reverse the cleaned string.
  5. Compare the cleaned string with its reverse. If they match, return true.

Visualization and Code

Loading animation...

This approach allocates a cleaned string and a reversed copy, both up to n characters. The next approach removes those allocations by comparing characters directly on the original string from both ends.

Approach 2: Two Pointers (Optimal)

Intuition

Work directly on the original string instead of building a cleaned copy. Place one pointer at the start and one at the end. Move them toward each other, skipping any character that isn't alphanumeric. When both pointers rest on alphanumeric characters, compare them case-insensitively. If they ever differ, the string is not a palindrome. If the pointers cross without a mismatch, it is.

This does the filtering and comparison in a single pass, with no extra string allocated.

Algorithm

  1. Set left to 0 and right to the last index of the string.
  2. While left < right:
    • If s[left] is not alphanumeric, advance left and start the next iteration.
    • If s[right] is not alphanumeric, move right back and start the next iteration.
    • Both pointers now rest on alphanumeric characters. Compare their lowercase versions.
    • If they don't match, return false.
    • Move left forward and right backward.
  3. Return true.

Visualization and Code

Loading animation...