diff --git a/solution/0400-0499/0409.Longest Palindrome/README.md b/solution/0400-0499/0409.Longest Palindrome/README.md index cb7100e471835..1da632a01076c 100644 --- a/solution/0400-0499/0409.Longest Palindrome/README.md +++ b/solution/0400-0499/0409.Longest Palindrome/README.md @@ -183,4 +183,104 @@ impl Solution { + + +### 方法二:位运算 + 计数 + +我们可以使用一个数组或哈希表 $odd$ 记录字符串 $s$ 中每个字符是否出现奇数次,用一个整型变量 $cnt$ 记录出现奇数次的字符个数。 + +遍历字符串 $s$,对于每个字符 $c$,将 $odd[c]$ 取反,即 $0 \rightarrow 1$, $1 \rightarrow 0$。如果 $odd[c]$ 由 $0$ 变为 $1$,则 $cnt$ 加一;如果 $odd[c]$ 由 $1$ 变为 $0$,则 $cnt$ 减一。 + +最后,如果 $cnt$ 大于 $0$,答案为 $n - cnt + 1$,否则答案为 $n$。 + +时间复杂度 $O(n)$,空间复杂度 $O(|\Sigma|)$。其中,$n$ 为字符串 $s$ 的长度,而 $|\Sigma|$ 为字符集大小,在本题中 $|\Sigma| = 128$。 + + + +#### Python3 + +```python +class Solution: + def longestPalindrome(self, s: str) -> int: + odd = defaultdict(int) + cnt = 0 + for c in s: + odd[c] ^= 1 + cnt += 1 if odd[c] else -1 + return len(s) - cnt + 1 if cnt else len(s) +``` + +#### Java + +```java +class Solution { + public int longestPalindrome(String s) { + int[] odd = new int[128]; + int n = s.length(); + int cnt = 0; + for (int i = 0; i < n; ++i) { + odd[s.charAt(i)] ^= 1; + cnt += odd[s.charAt(i)] == 1 ? 1 : -1; + } + return cnt > 0 ? n - cnt + 1 : n; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestPalindrome(string s) { + int odd[128]{}; + int n = s.length(); + int cnt = 0; + for (char& c : s) { + odd[c] ^= 1; + cnt += odd[c] ? 1 : -1; + } + return cnt ? n - cnt + 1 : n; + } +}; +``` + +#### Go + +```go +func longestPalindrome(s string) (ans int) { + odd := [128]int{} + cnt := 0 + for _, c := range s { + odd[c] ^= 1 + cnt += odd[c] + if odd[c] == 0 { + cnt-- + } + } + if cnt > 0 { + return len(s) - cnt + 1 + } + return len(s) +} +``` + +#### TypeScript + +```ts +function longestPalindrome(s: string): number { + const odd: Record = {}; + let cnt = 0; + for (const c of s) { + odd[c] ^= 1; + cnt += odd[c] ? 1 : -1; + } + return cnt ? s.length - cnt + 1 : s.length; +} +``` + + + + + diff --git a/solution/0400-0499/0409.Longest Palindrome/README_EN.md b/solution/0400-0499/0409.Longest Palindrome/README_EN.md index e4a9170a87ff2..076e5ff020358 100644 --- a/solution/0400-0499/0409.Longest Palindrome/README_EN.md +++ b/solution/0400-0499/0409.Longest Palindrome/README_EN.md @@ -180,4 +180,104 @@ impl Solution { + + +### Solution 2: Bit Manipulation + Counting + +We can use an array or hash table $odd$ to record whether each character in string $s$ appears an odd number of times, and an integer variable $cnt$ to record the number of characters that appear an odd number of times. + +We iterate through the string $s$. For each character $c$, we flip $odd[c]$, i.e., $0 \rightarrow 1$, $1 \rightarrow 0$. If $odd[c]$ changes from $0$ to $1$, then we increment $cnt$ by one; if $odd[c]$ changes from $1$ to $0$, then we decrement $cnt$ by one. + +Finally, if $cnt$ is greater than $0$, the answer is $n - cnt + 1$, otherwise, the answer is $n$. + +The time complexity is $O(n)$, and the space complexity is $O(|\Sigma|)$. Where $n$ is the length of the string $s$, and $|\Sigma|$ is the size of the character set. In this problem, $|\Sigma| = 128$. + + + +#### Python3 + +```python +class Solution: + def longestPalindrome(self, s: str) -> int: + odd = defaultdict(int) + cnt = 0 + for c in s: + odd[c] ^= 1 + cnt += 1 if odd[c] else -1 + return len(s) - cnt + 1 if cnt else len(s) +``` + +#### Java + +```java +class Solution { + public int longestPalindrome(String s) { + int[] odd = new int[128]; + int n = s.length(); + int cnt = 0; + for (int i = 0; i < n; ++i) { + odd[s.charAt(i)] ^= 1; + cnt += odd[s.charAt(i)] == 1 ? 1 : -1; + } + return cnt > 0 ? n - cnt + 1 : n; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestPalindrome(string s) { + int odd[128]{}; + int n = s.length(); + int cnt = 0; + for (char& c : s) { + odd[c] ^= 1; + cnt += odd[c] ? 1 : -1; + } + return cnt ? n - cnt + 1 : n; + } +}; +``` + +#### Go + +```go +func longestPalindrome(s string) (ans int) { + odd := [128]int{} + cnt := 0 + for _, c := range s { + odd[c] ^= 1 + cnt += odd[c] + if odd[c] == 0 { + cnt-- + } + } + if cnt > 0 { + return len(s) - cnt + 1 + } + return len(s) +} +``` + +#### TypeScript + +```ts +function longestPalindrome(s: string): number { + const odd: Record = {}; + let cnt = 0; + for (const c of s) { + odd[c] ^= 1; + cnt += odd[c] ? 1 : -1; + } + return cnt ? s.length - cnt + 1 : s.length; +} +``` + + + + + diff --git a/solution/0400-0499/0409.Longest Palindrome/Solution2.cpp b/solution/0400-0499/0409.Longest Palindrome/Solution2.cpp new file mode 100644 index 0000000000000..7389a5d94d56a --- /dev/null +++ b/solution/0400-0499/0409.Longest Palindrome/Solution2.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + int longestPalindrome(string s) { + int odd[128]{}; + int n = s.length(); + int cnt = 0; + for (char& c : s) { + odd[c] ^= 1; + cnt += odd[c] ? 1 : -1; + } + return cnt ? n - cnt + 1 : n; + } +}; diff --git a/solution/0400-0499/0409.Longest Palindrome/Solution2.go b/solution/0400-0499/0409.Longest Palindrome/Solution2.go new file mode 100644 index 0000000000000..2031f84d0897e --- /dev/null +++ b/solution/0400-0499/0409.Longest Palindrome/Solution2.go @@ -0,0 +1,15 @@ +func longestPalindrome(s string) (ans int) { + odd := [128]int{} + cnt := 0 + for _, c := range s { + odd[c] ^= 1 + cnt += odd[c] + if odd[c] == 0 { + cnt-- + } + } + if cnt > 0 { + return len(s) - cnt + 1 + } + return len(s) +} diff --git a/solution/0400-0499/0409.Longest Palindrome/Solution2.java b/solution/0400-0499/0409.Longest Palindrome/Solution2.java new file mode 100644 index 0000000000000..3f26683887b89 --- /dev/null +++ b/solution/0400-0499/0409.Longest Palindrome/Solution2.java @@ -0,0 +1,12 @@ +class Solution { + public int longestPalindrome(String s) { + int[] odd = new int[128]; + int n = s.length(); + int cnt = 0; + for (int i = 0; i < n; ++i) { + odd[s.charAt(i)] ^= 1; + cnt += odd[s.charAt(i)] == 1 ? 1 : -1; + } + return cnt > 0 ? n - cnt + 1 : n; + } +} diff --git a/solution/0400-0499/0409.Longest Palindrome/Solution2.py b/solution/0400-0499/0409.Longest Palindrome/Solution2.py new file mode 100644 index 0000000000000..28d3e572e1901 --- /dev/null +++ b/solution/0400-0499/0409.Longest Palindrome/Solution2.py @@ -0,0 +1,8 @@ +class Solution: + def longestPalindrome(self, s: str) -> int: + odd = defaultdict(int) + cnt = 0 + for c in s: + odd[c] ^= 1 + cnt += 1 if odd[c] else -1 + return len(s) - cnt + 1 if cnt else len(s) diff --git a/solution/0400-0499/0409.Longest Palindrome/Solution2.ts b/solution/0400-0499/0409.Longest Palindrome/Solution2.ts new file mode 100644 index 0000000000000..10ae8b4d79fdb --- /dev/null +++ b/solution/0400-0499/0409.Longest Palindrome/Solution2.ts @@ -0,0 +1,9 @@ +function longestPalindrome(s: string): number { + const odd: Record = {}; + let cnt = 0; + for (const c of s) { + odd[c] ^= 1; + cnt += odd[c] ? 1 : -1; + } + return cnt ? s.length - cnt + 1 : s.length; +}