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^5sconsists 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 iti++.s[j]is not alphanumeric - we can skip itj--.- both are alphanumeric - compare the two values. If they are not equal then
return falseelse 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