Valid Palindrome
Easy · Two Pointers · Explanation and code example
Two Pointers
How it works
Instead of building a new string, we can check the palindrome directly in-place using two pointers.
One pointer starts at the beginning (l) and the other at the end (r).
We move both pointers inward, skipping any characters that are not letters or digits.
Whenever both pointers point to valid characters, we compare them in lowercase form.
If at any point they differ, the string is not a palindrome.
This method avoids extra space and keeps the logic simple and efficient.
Steps
- Initialize two pointers:
lat the start of the string,rat the end of the string.
- While
lis less thanr:- Move
lforward until it points to an alphanumeric character. - Move
rbackward until it points to an alphanumeric character. - Compare the lowercase characters at
landr:- If they don't match, return
false.
- If they don't match, return
- Move both pointers inward:
l += 1,r -= 1.
- Move
- If the loop finishes without mismatches, return
true.
Complexity
- Time complexity:
O(n) - Space complexity:
O(1)
Things to watch for
Not Skipping Non-Alphanumeric Characters
The problem requires ignoring all characters that are not letters or digits. Forgetting to skip spaces, punctuation, and special characters will cause false negatives. For example, "A man, a plan, a canal: Panama" should be recognized as a palindrome, but including the spaces and punctuation in the comparison will incorrectly return false.
Case Sensitivity
Letters must be compared in a case-insensitive manner. Comparing 'A' directly with 'a' will return false even though they should be treated as equal. Always convert both characters to the same case (lowercase or uppercase) before comparing.
Python code example
class Solution:
def isPalindrome(self, s: str) -> bool:
l, r = 0, len(s) - 1
while l < r:
while l < r and not self.alphaNum(s[l]):
l += 1
while r > l and not self.alphaNum(s[r]):
r -= 1
if s[l].lower() != s[r].lower():
return False
l, r = l + 1, r - 1
return True
def alphaNum(self, c):
return (ord('A') <= ord(c) <= ord('Z') or
ord('a') <= ord(c) <= ord('z') or
ord('0') <= ord(c) <= ord('9'))
C++ code example
class Solution {
public:
bool isPalindrome(string s) {
int l = 0, r = s.length() - 1;
while (l < r) {
while (l < r && !alphaNum(s[l])) {
l++;
}
while (r > l && !alphaNum(s[r])) {
r--;
}
if (tolower(s[l]) != tolower(s[r])) {
return false;
}
l++; r--;
}
return true;
}
bool alphaNum(char c) {
return (c >= 'A' && c <= 'Z' ||
c >= 'a' && c <= 'z' ||
c >= '0' && c <= '9');
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.