From 1140934f0389809c9ab744d21e1c271379acf299 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Thu, 20 Apr 2023 22:17:54 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.0125 No.0125.Valid Palindrome --- .../0100-0199/0125.Valid Palindrome/README.md | 200 +++++++----------- .../0125.Valid Palindrome/README_EN.md | 187 ++++++---------- .../0125.Valid Palindrome/Solution.cpp | 16 +- .../0125.Valid Palindrome/Solution.cs | 17 +- .../0125.Valid Palindrome/Solution.go | 34 +-- .../0125.Valid Palindrome/Solution.java | 2 +- .../0125.Valid Palindrome/Solution.js | 24 ++- .../0125.Valid Palindrome/Solution.py | 13 ++ .../0125.Valid Palindrome/Solution.ts | 22 +- 9 files changed, 211 insertions(+), 304 deletions(-) create mode 100644 solution/0100-0199/0125.Valid Palindrome/Solution.py diff --git a/solution/0100-0199/0125.Valid Palindrome/README.md b/solution/0100-0199/0125.Valid Palindrome/README.md index c53645aed491e..c7146421a7ba6 100644 --- a/solution/0100-0199/0125.Valid Palindrome/README.md +++ b/solution/0100-0199/0125.Valid Palindrome/README.md @@ -52,6 +52,19 @@ +**方法一:双指针** + +我们用双指针 $i$ 和 $j$ 分别指向字符串 $s$ 的两端,接下来循环以下过程,直至 $i \geq j$: + +1. 如果 $s[i]$ 不是字母或数字,指针 $i$ 右移一位,继续下一次循环; +1. 如果 $s[j]$ 不是字母或数字,指针 $j$ 左移一位,继续下一次循环; +1. 如果 $s[i]$ 和 $s[j]$ 的小写形式不相等,返回 `false`; +1. 否则,指针 $i$ 右移一位,指针 $j$ 左移一位,继续下一次循环。 + +循环结束,返回 `true`。 + +时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(1)$。 + ### **Python3** @@ -70,8 +83,7 @@ class Solution: elif s[i].lower() != s[j].lower(): return False else: - i += 1 - j -= 1 + i, j = i + 1, j - 1 return True ``` @@ -88,7 +100,7 @@ class Solution { ++i; } else if (!Character.isLetterOrDigit(s.charAt(j))) { --j; - } else if (Character.toUpperCase(s.charAt(i)) != Character.toUpperCase(s.charAt(j))) { + } else if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) { return false; } else { ++i; @@ -108,43 +120,67 @@ public: bool isPalindrome(string s) { int i = 0, j = s.size() - 1; while (i < j) { - if (!isAlphaNum(s[i])) + if (!isalnum(s[i])) { ++i; - else if (!isAlphaNum(s[j])) + } else if (!isalnum(s[j])) { --j; - else if ((s[i] + 32 - 'a') % 32 != (s[j] + 32 - 'a') % 32) + } else if (tolower(s[i]) != tolower(s[j])) { return false; - else { + } else { ++i; --j; } } return true; } - -private: - bool isAlphaNum(char& ch) { - if (ch >= 'a' && ch <= 'z') return true; - if (ch >= 'A' && ch <= 'Z') return true; - if (ch >= '0' && ch <= '9') return true; - return false; - } }; ``` +### **Go** + +```go +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 +} +``` + ### **C#** ```cs -using System.Linq; - public class Solution { public bool IsPalindrome(string s) { - var chars = s.Where(ch => char.IsLetterOrDigit(ch)).Select(char.ToLower).ToList(); - var i = 0; - var j = chars.Count - 1; - for (; i < j; ++i, --j) - { - if (chars[i] != chars[j]) return false; + 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; } @@ -159,57 +195,18 @@ public class Solution { * @return {boolean} */ var isPalindrome = function (s) { - let arr1 = [], - arr2 = []; - for (let i = 0; i < s.length; i++) { - if (s[i] >= 'A' && s[i] <= 'Z') { - arr1.push(s[i].toLowerCase()); - } - if ((s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z')) { - arr1.push(s[i]); - } - } - arr2 = [...arr1]; - arr2.reverse(); - return arr1.join('') === arr2.join(''); -}; -``` - -```js -/** - * @param {string} s - * @return {boolean} - */ -var isPalindrome = function (s) { - function isNumOrAl(a) { - if ( - (a >= 'A' && a <= 'Z') || - (a >= '0' && a <= '9') || - (a >= 'a' && a <= 'z') - ) { - return true; - } else { - return false; - } - } - - if (s.length === 0) { - return true; - } - let i = 0, - j = s.length - 1; + let i = 0; + let j = s.length - 1; while (i < j) { - while (i < j && !isNumOrAl(s[i])) { - i++; - } - while (i < j && !isNumOrAl(s[j])) { - j--; - } - if (s[i].toLowerCase() !== s[j].toLowerCase()) { + 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--; + ++i; + --j; } } return true; @@ -220,36 +217,24 @@ var isPalindrome = function (s) { ```ts function isPalindrome(s: string): boolean { - let left: number = 0, - right: number = s.length - 1; - while (left < right) { - let char1: string = s.charAt(left); - let char2: string = s.charAt(right); - if (!/[a-zA-Z0-9]/.test(char1)) { - ++left; - } else if (!/[a-zA-Z0-9]/.test(char2)) { - --right; - } else if (char1.toLocaleLowerCase() != char2.toLocaleLowerCase()) { + 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 { - ++left; - --right; + ++i; + --j; } } return true; } ``` -```ts -function isPalindrome(s: string): boolean { - const isAlphanumeric = (c: string) => { - return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'); - }; - const cs = s.toLocaleLowerCase().split('').filter(isAlphanumeric); - return cs.join('') === cs.reverse().join(''); -} -``` - ### **Rust** ```rust @@ -279,35 +264,6 @@ impl Solution { } ``` -### **Go** - -```go -func isPalindrome(s string) bool { - s = strings.ToLower(s) - left, right := 0, len(s) - 1 - for left < right { - for left < right && !verify(s[left]) { - left++ - } - for left < right && !verify(s[right]) { - right-- - } - if left < right { - if s[left] != s[right] { - return false - } - left++ - right-- - } - } - return true -} - -func verify(ch byte) bool { - return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') -} -``` - ### **PHP** ```php diff --git a/solution/0100-0199/0125.Valid Palindrome/README_EN.md b/solution/0100-0199/0125.Valid Palindrome/README_EN.md index 38d356d454fb3..d474fe9e13764 100644 --- a/solution/0100-0199/0125.Valid Palindrome/README_EN.md +++ b/solution/0100-0199/0125.Valid Palindrome/README_EN.md @@ -60,8 +60,7 @@ class Solution: elif s[i].lower() != s[j].lower(): return False else: - i += 1 - j -= 1 + i, j = i + 1, j - 1 return True ``` @@ -76,7 +75,7 @@ class Solution { ++i; } else if (!Character.isLetterOrDigit(s.charAt(j))) { --j; - } else if (Character.toUpperCase(s.charAt(i)) != Character.toUpperCase(s.charAt(j))) { + } else if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) { return false; } else { ++i; @@ -96,43 +95,67 @@ public: bool isPalindrome(string s) { int i = 0, j = s.size() - 1; while (i < j) { - if (!isAlphaNum(s[i])) + if (!isalnum(s[i])) { ++i; - else if (!isAlphaNum(s[j])) + } else if (!isalnum(s[j])) { --j; - else if ((s[i] + 32 - 'a') % 32 != (s[j] + 32 - 'a') % 32) + } else if (tolower(s[i]) != tolower(s[j])) { return false; - else { + } else { ++i; --j; } } return true; } - -private: - bool isAlphaNum(char& ch) { - if (ch >= 'a' && ch <= 'z') return true; - if (ch >= 'A' && ch <= 'Z') return true; - if (ch >= '0' && ch <= '9') return true; - return false; - } }; ``` +### **Go** + +```go +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 +} +``` + ### **C#** ```cs -using System.Linq; - public class Solution { public bool IsPalindrome(string s) { - var chars = s.Where(ch => char.IsLetterOrDigit(ch)).Select(char.ToLower).ToList(); - var i = 0; - var j = chars.Count - 1; - for (; i < j; ++i, --j) - { - if (chars[i] != chars[j]) return false; + 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; } @@ -147,57 +170,18 @@ public class Solution { * @return {boolean} */ var isPalindrome = function (s) { - let arr1 = [], - arr2 = []; - for (let i = 0; i < s.length; i++) { - if (s[i] >= 'A' && s[i] <= 'Z') { - arr1.push(s[i].toLowerCase()); - } - if ((s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z')) { - arr1.push(s[i]); - } - } - arr2 = [...arr1]; - arr2.reverse(); - return arr1.join('') === arr2.join(''); -}; -``` - -```js -/** - * @param {string} s - * @return {boolean} - */ -var isPalindrome = function (s) { - function isNumOrAl(a) { - if ( - (a >= 'A' && a <= 'Z') || - (a >= '0' && a <= '9') || - (a >= 'a' && a <= 'z') - ) { - return true; - } else { - return false; - } - } - - if (s.length === 0) { - return true; - } - let i = 0, - j = s.length - 1; + let i = 0; + let j = s.length - 1; while (i < j) { - while (i < j && !isNumOrAl(s[i])) { - i++; - } - while (i < j && !isNumOrAl(s[j])) { - j--; - } - if (s[i].toLowerCase() !== s[j].toLowerCase()) { + 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--; + ++i; + --j; } } return true; @@ -208,36 +192,24 @@ var isPalindrome = function (s) { ```ts function isPalindrome(s: string): boolean { - let left: number = 0, - right: number = s.length - 1; - while (left < right) { - let char1: string = s.charAt(left); - let char2: string = s.charAt(right); - if (!/[a-zA-Z0-9]/.test(char1)) { - ++left; - } else if (!/[a-zA-Z0-9]/.test(char2)) { - --right; - } else if (char1.toLocaleLowerCase() != char2.toLocaleLowerCase()) { + 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 { - ++left; - --right; + ++i; + --j; } } return true; } ``` -```ts -function isPalindrome(s: string): boolean { - const isAlphanumeric = (c: string) => { - return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'); - }; - const cs = s.toLocaleLowerCase().split('').filter(isAlphanumeric); - return cs.join('') === cs.reverse().join(''); -} -``` - ### **Rust** ```rust @@ -267,35 +239,6 @@ impl Solution { } ``` -### **Go** - -```go -func isPalindrome(s string) bool { - s = strings.ToLower(s) - left, right := 0, len(s) - 1 - for left < right { - for left < right && !verify(s[left]) { - left++ - } - for left < right && !verify(s[right]) { - right-- - } - if left < right { - if s[left] != s[right] { - return false - } - left++ - right-- - } - } - return true -} - -func verify(ch byte) bool { - return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') -} -``` - ### **PHP** ```php diff --git a/solution/0100-0199/0125.Valid Palindrome/Solution.cpp b/solution/0100-0199/0125.Valid Palindrome/Solution.cpp index 242b625b1c58b..bbc2773e14d1e 100644 --- a/solution/0100-0199/0125.Valid Palindrome/Solution.cpp +++ b/solution/0100-0199/0125.Valid Palindrome/Solution.cpp @@ -3,25 +3,17 @@ class Solution { bool isPalindrome(string s) { int i = 0, j = s.size() - 1; while (i < j) { - if (!isAlphaNum(s[i])) + if (!isalnum(s[i])) { ++i; - else if (!isAlphaNum(s[j])) + } else if (!isalnum(s[j])) { --j; - else if ((s[i] + 32 - 'a') % 32 != (s[j] + 32 - 'a') % 32) + } else if (tolower(s[i]) != tolower(s[j])) { return false; - else { + } else { ++i; --j; } } return true; } - -private: - bool isAlphaNum(char& ch) { - if (ch >= 'a' && ch <= 'z') return true; - if (ch >= 'A' && ch <= 'Z') return true; - if (ch >= '0' && ch <= '9') return true; - return false; - } }; \ No newline at end of file diff --git a/solution/0100-0199/0125.Valid Palindrome/Solution.cs b/solution/0100-0199/0125.Valid Palindrome/Solution.cs index dc2c4e9ad4223..594b7e02f1f13 100644 --- a/solution/0100-0199/0125.Valid Palindrome/Solution.cs +++ b/solution/0100-0199/0125.Valid Palindrome/Solution.cs @@ -1,13 +1,14 @@ -using System.Linq; - public class Solution { public bool IsPalindrome(string s) { - var chars = s.Where(ch => char.IsLetterOrDigit(ch)).Select(char.ToLower).ToList(); - var i = 0; - var j = chars.Count - 1; - for (; i < j; ++i, --j) - { - if (chars[i] != chars[j]) return false; + 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; } diff --git a/solution/0100-0199/0125.Valid Palindrome/Solution.go b/solution/0100-0199/0125.Valid Palindrome/Solution.go index 5b3ddec918777..47319af9e8632 100644 --- a/solution/0100-0199/0125.Valid Palindrome/Solution.go +++ b/solution/0100-0199/0125.Valid Palindrome/Solution.go @@ -1,24 +1,26 @@ func isPalindrome(s string) bool { - s = strings.ToLower(s) - left, right := 0, len(s) - 1 - for left < right { - for left < right && !verify(s[left]) { - left++ - } - for left < right && !verify(s[right]) { - right-- - } - if left < right { - if s[left] != s[right] { - return false - } - left++ - right-- + 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 verify(ch byte) bool { +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 } \ No newline at end of file diff --git a/solution/0100-0199/0125.Valid Palindrome/Solution.java b/solution/0100-0199/0125.Valid Palindrome/Solution.java index 5df0ee2d50e76..1bf028c1f616c 100644 --- a/solution/0100-0199/0125.Valid Palindrome/Solution.java +++ b/solution/0100-0199/0125.Valid Palindrome/Solution.java @@ -6,7 +6,7 @@ public boolean isPalindrome(String s) { ++i; } else if (!Character.isLetterOrDigit(s.charAt(j))) { --j; - } else if (Character.toUpperCase(s.charAt(i)) != Character.toUpperCase(s.charAt(j))) { + } else if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) { return false; } else { ++i; diff --git a/solution/0100-0199/0125.Valid Palindrome/Solution.js b/solution/0100-0199/0125.Valid Palindrome/Solution.js index f4d728dd21261..edde5786b0397 100644 --- a/solution/0100-0199/0125.Valid Palindrome/Solution.js +++ b/solution/0100-0199/0125.Valid Palindrome/Solution.js @@ -3,17 +3,19 @@ * @return {boolean} */ var isPalindrome = function (s) { - let arr1 = [], - arr2 = []; - for (let i = 0; i < s.length; i++) { - if (s[i] >= 'A' && s[i] <= 'Z') { - arr1.push(s[i].toLowerCase()); - } - if ((s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z')) { - arr1.push(s[i]); + 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; } } - arr2 = [...arr1]; - arr2.reverse(); - return arr1.join('') === arr2.join(''); + return true; }; diff --git a/solution/0100-0199/0125.Valid Palindrome/Solution.py b/solution/0100-0199/0125.Valid Palindrome/Solution.py new file mode 100644 index 0000000000000..73fac29a8c02d --- /dev/null +++ b/solution/0100-0199/0125.Valid Palindrome/Solution.py @@ -0,0 +1,13 @@ +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 diff --git a/solution/0100-0199/0125.Valid Palindrome/Solution.ts b/solution/0100-0199/0125.Valid Palindrome/Solution.ts index 4daab16efc9f7..b06244fa3c279 100644 --- a/solution/0100-0199/0125.Valid Palindrome/Solution.ts +++ b/solution/0100-0199/0125.Valid Palindrome/Solution.ts @@ -1,18 +1,16 @@ function isPalindrome(s: string): boolean { - let left: number = 0, - right: number = s.length - 1; - while (left < right) { - let char1: string = s.charAt(left); - let char2: string = s.charAt(right); - if (!/[a-zA-Z0-9]/.test(char1)) { - ++left; - } else if (!/[a-zA-Z0-9]/.test(char2)) { - --right; - } else if (char1.toLocaleLowerCase() != char2.toLocaleLowerCase()) { + 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 { - ++left; - --right; + ++i; + --j; } } return true;