[/dsa/leetcode]

125 - Valid Palindrome

Wednesday, 16 September 2026

<easy> [problem]

Converging pointers that skip non-alphanumeric characters in place, so the filtered string is never actually built.

{string}{two pointers}

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.

Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome

Input: s = "race a car"
Output: false

Input: s = " "
Output: true
Explanation: after removing non-alphanumeric characters the string is empty

Constraints:

  • 1 <= s.length <= 2 * 10^5
  • s consists only of printable ASCII characters

Approach

We create two pointers, i from the left, j from the right as if a string is palindrome its last and first character must be same:

  • s[i] is not alphanumeric - we can skip it i++ .
  • s[j] is not alphanumeric - we can skip it j--.
  • both are alphanumeric - compare the two values. If they are not equal then return false else progress the pointers.
class Solution {
public:
    bool isPalindrome(string str) {
        int i = 0;
        int j = str.length() - 1;
        while (i < j) {
            if (!isalnum(str[i])) {
                i++;
                continue;
            }
            if (!isalnum(str[j])) {
                j--;
                continue;
            }
            if (tolower(str[i]) != tolower(str[j])) {
                return false;
            } else {
                i++;
                j--;
            }
        }
        return true;
    }
};
s = "A man, a plan, a canal: Panama"
     ^                            ^     'a' == 'a'  ->  both move
      ^                          ^      ' ' skipped, then 'm' == 'm'
       ...
                  ^   ^                 eventually i >= j  ->  true

s = "race a car"
     ^        ^     'r' == 'r'
      ^      ^      'a' == 'a'
       ^    ^       'c' vs 'a'  ->  false
  • time: O(n) — each character is visited at most once by one pointer
  • space: O(1) — two indices, no filtered copy
quantinium © 2026