125. Valid Palindrome - Explanation
Description
Given a string s, return true if it is a palindrome, otherwise return false.
A palindrome is a string that reads the same forward and backward. It is also case-insensitive and ignores all non-alphanumeric characters.
Note: Alphanumeric characters consist of letters (A-Z, a-z) and numbers (0-9).
Example 1:
Input: s = "Was it a car or a cat I saw?"
Output: trueExplanation: After considering only alphanumerical characters we have "wasitacaroracatisaw", which is a palindrome.
Example 2:
Input: s = "tab a cat"
Output: falseExplanation: "tabacat" is not a palindrome.
Constraints:
1 <= s.length <= 1000sis made up of only printable ASCII characters.
Topics
Recommended Time & Space Complexity
You should aim for a solution with O(n) time and O(1) space, where n is the length of the input string.
Hint 1
A brute force solution would be to create a copy of the string, reverse it, and then check for equality. This would be an O(n) solution with extra space. Can you think of a way to do this without O(n) space?
Hint 2
Can you find the logic by observing the definition of pallindrome or from the brute force solution?
Hint 3
A palindrome string is a string that is read the same from the start as well as from the end. This means the character at the start should match the character at the end at the same index. We can use the two pointer algorithm to do this efficiently.
Prerequisites
Before attempting this problem, you should be comfortable with:
- Two Pointers - Using pointers from both ends of a string to compare characters efficiently
- String Manipulation - Filtering characters, converting case, and reversing strings
- Character Classification - Identifying alphanumeric vs non-alphanumeric characters
1. Reverse String
Intuition
To check if a string is a palindrome, we only care about letters and digits—everything else can be ignored.
We can build a cleaned version of the string that contains only alphanumeric characters, all converted to lowercase for consistency.
Once we have this cleaned string, the problem becomes very simple:
a string is a palindrome if it is exactly the same as its reverse.
Algorithm
- Create an empty string
newStr. - Loop through each character
cin the input string:- If
cis alphanumeric, convert it to lowercase and add it tonewStr.
- If
- Compare
newStrwith its reverse (newStr[::-1]):- If they are equal, return
true. - Otherwise, return
false.
- If they are equal, return
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Two Pointers
Intuition
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.
Algorithm
- 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.
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'))Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
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.
Sign in to join the discussion