Welcome to Subscribe On Youtube
125. Valid Palindrome
Description
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)$.
-
class Solution { public boolean isPalindrome(String s) { int i = 0, j = s.length() - 1; while (i < j) { if (!Character.isLetterOrDigit(s.charAt(i))) { ++i; } else if (!Character.isLetterOrDigit(s.charAt(j))) { --j; } else if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) { return false; } else { ++i; --j; } } return true; } }
-
class Solution { public: bool isPalindrome(string s) { int i = 0, j = s.size() - 1; while (i < j) { if (!isalnum(s[i])) { ++i; } else if (!isalnum(s[j])) { --j; } else if (tolower(s[i]) != tolower(s[j])) { return false; } else { ++i; --j; } } return true; } };
-
class Solution: def isPalindrome(self, s: str) -> bool: i, j = 0, len(s) - 1 while i < j: if not s[i].isalnum(): i += 1 elif not s[j].isalnum(): j -= 1 elif s[i].lower() != s[j].lower(): return False else: i, j = i + 1, j - 1 return True
-
func isPalindrome(s string) bool { i, j := 0, len(s)-1 for i < j { if !isalnum(s[i]) { i++ } else if !isalnum(s[j]) { j-- } else if tolower(s[i]) != tolower(s[j]) { return false } else { i, j = i+1, j-1 } } return true } func isalnum(ch byte) bool { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') } func tolower(ch byte) byte { if ch >= 'A' && ch <= 'Z' { return ch + 32 } return ch }
-
function isPalindrome(s: string): boolean { let i = 0; let j = s.length - 1; while (i < j) { if (!/[a-zA-Z0-9]/.test(s[i])) { ++i; } else if (!/[a-zA-Z0-9]/.test(s[j])) { --j; } else if (s[i].toLowerCase() !== s[j].toLowerCase()) { return false; } else { ++i; --j; } } return true; }
-
/** * @param {string} s * @return {boolean} */ var isPalindrome = function (s) { let i = 0; let j = s.length - 1; while (i < j) { if (!/[a-zA-Z0-9]/.test(s[i])) { ++i; } else if (!/[a-zA-Z0-9]/.test(s[j])) { --j; } else if (s[i].toLowerCase() !== s[j].toLowerCase()) { return false; } else { ++i; --j; } } return true; };
-
class Solution { /** * @param String $s * @return Boolean */ function isPalindrome($s) { $regex = '/[a-z0-9]/'; $s = strtolower($s); preg_match_all($regex, $s, $matches); if ($matches[0] == null) { return true; } $len = floor(count($matches[0]) / 2); for ($i = 0; $i < $len; $i++) { if ($matches[0][$i] != $matches[0][count($matches[0]) - 1 - $i]) { return false; } } return true; } }
-
public class Solution { public bool IsPalindrome(string s) { int i = 0, j = s.Length - 1; while (i < j) { if (!char.IsLetterOrDigit(s[i])) { ++i; } else if (!char.IsLetterOrDigit(s[j])) { --j; } else if (char.ToLower(s[i++]) != char.ToLower(s[j--])) { return false; } } return true; } }
-
impl Solution { pub fn is_palindrome(s: String) -> bool { let s = s.to_lowercase(); let s = s.as_bytes(); let n = s.len(); let (mut l, mut r) = (0, n - 1); while l < r { while l < r && !s[l].is_ascii_alphanumeric() { l += 1; } while l < r && !s[r].is_ascii_alphanumeric() { r -= 1; } if s[l] != s[r] { return false; } l += 1; if r != 0 { r -= 1; } } true } }