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.
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.
Constraints:
1 <= s.length <= 2 * 105
s consists only of printable ASCII characters.
Solutions
Solution 1: Two Pointers
We use two pointers \(i\) and \(j\) to point to the two ends of the string \(s\), and then loop through the following process until \(i \geq j\):
If \(s[i]\) is not a letter or a number, move the pointer \(i\) one step to the right and continue to the next loop.
If \(s[j]\) is not a letter or a number, move the pointer \(j\) one step to the left and continue to the next loop.
If the lowercase form of \(s[i]\) and \(s[j]\) are not equal, return false.
Otherwise, move the pointer \(i\) one step to the right and the pointer \(j\) one step to the left, and continue to the next loop.
At the end of the loop, return true.
The time complexity is \(O(n)\), where \(n\) is the length of the string \(s\). The space complexity is \(O(1)\).