Problem Statement
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 a palindrome, or false
otherwise.
LeetCode
Constraints
1 <= s.length <= 2 * 10^5
s consists only of printable ASCII characters.
Examples
Example 1:
Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.
Example 2:
Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.
Example 3:
Input: s = " "
Output: true
Explanation: s is an empty string "" after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.
Different Approaches
1️⃣ Two Pointers
🧠 Idea:
- Use two pointers:
- one from the start and one from the end.
- Skip non-alphanumerics, compare lowercase letters.
Code:
bool isPalindrome(string s) {
int left = 0, right = s.size() - 1;
while (left < right) {
// Skip non-alphanumerics
while (left < right && !isalnum(s[left])) left++;
while (left < right && !isalnum(s[right])) right--;
// Compare lowercased characters
if (tolower(s[left]) != tolower(s[right])) return false;
left++;
right--;
}
return true;
}
Complexity Analysis:
- Time Complexity:
O(n)
- Space Complexity:
O(1)
2️⃣ Clean and Reverse
🧠 Idea:
- Clean the string (only alphanumeric + lowercase).
- Compare it with its reverse.
Code:
bool isPalindrome(string s) {
string clean = "";
for (char c : s) {
if (isalnum(c)) clean += tolower(c);
}
string rev = clean;
reverse(rev.begin(), rev.end());
return clean == rev;
}
Complexity Analysis:
- Time Complexity:
O(n)
- Space Complexity:
O(1)
3️⃣ Recursive
🧠 Idea:
- Use a helper function that takes two indices left and right.
- Skip non-alphanumeric characters.
- Compare lowercase characters.
- Recur inward.
Code:
class Solution {
public:
bool isPalindrome(string& s, int left, int right) {
// Base case: pointers crossed
if (left >= right) return true;
// Skip non-alphanumerics
if (!isalnum(s[left])) return isPalindrome(s, left + 1, right);
if (!isalnum(s[right])) return isPalindrome(s, left, right - 1);
// Compare lowercase characters
if (tolower(s[left]) != tolower(s[right])) return false;
// Recur inward
return isPalindrome(s, left + 1, right - 1);
}
bool isPalindrome(string s) {
return isPalindrome(s, 0, s.size() - 1);
}
};
Complexity Analysis:
- Time Complexity:
O(n)
- Space Complexity:
O(1)