Skip to content

feat: add solutions to lc problem: No.409 #3021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 33 additions & 72 deletions solution/0400-0499/0409.Longest Palindrome/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ tags:

因此,我们可以先遍历字符串 $s$,统计每个字符出现的次数,记录在数组或哈希表 $cnt$ 中。

然后,我们遍历 $cnt$,对于每个字符 $c$,如果 $cnt[c]$ 为偶数,则直接将 $cnt[c]$ 累加到答案 $ans$ 中;如果 $cnt[c]$ 为奇数,则将 $cnt[c] - 1$ 累加到 $ans$ 中,如果 $ans$ 为偶数,则将 $ans$ 增加 $1$
然后,我们遍历 $cnt$,对于每个次数 $v$,将 $v$ 除以 2 取整,再乘以 2,累加到答案 $ans$

最后,我们返回 $ans$ 即可
最后,如果答案小于字符串 $s$ 的长度,则将答案加一,返回 $ans$

时间复杂度 $O(n)$,空间复杂度 $O(C)$。其中 $n$ 为字符串 $s$ 的长度而 $C$ 为字符集的大小,本题中 $C = 128$。
时间复杂度 $O(n + |\Sigma|)$,空间复杂度 $O(|\Sigma|)$。其中$n$ 为字符串 $s$ 的长度而 $|\Sigma|$ 为字符集大小,在本题中 $|\Sigma| = 128$。

<!-- tabs:start -->

Expand All @@ -76,10 +76,8 @@ tags:
class Solution:
def longestPalindrome(self, s: str) -> int:
cnt = Counter(s)
ans = 0
for v in cnt.values():
ans += v - (v & 1)
ans += (ans & 1 ^ 1) and (v & 1)
ans = sum(v // 2 * 2 for v in cnt.values())
ans += int(ans < len(s))
return ans
```

Expand All @@ -89,16 +87,15 @@ class Solution:
class Solution {
public int longestPalindrome(String s) {
int[] cnt = new int[128];
for (int i = 0; i < s.length(); ++i) {
int n = s.length();
for (int i = 0; i < n; ++i) {
++cnt[s.charAt(i)];
}
int ans = 0;
for (int v : cnt) {
ans += v - (v & 1);
if (ans % 2 == 0 && v % 2 == 1) {
++ans;
}
ans += v / 2 * 2;
}
ans += ans < n ? 1 : 0;
return ans;
}
}
Expand All @@ -111,16 +108,14 @@ class Solution {
public:
int longestPalindrome(string s) {
int cnt[128]{};
for (char& c : s) {
for (char c : s) {
++cnt[c];
}
int ans = 0;
for (int v : cnt) {
ans += v - (v & 1);
if (ans % 2 == 0 && v % 2 == 1) {
++ans;
}
ans += v / 2 * 2;
}
ans += ans < s.size();
return ans;
}
};
Expand All @@ -135,10 +130,10 @@ func longestPalindrome(s string) (ans int) {
cnt[c]++
}
for _, v := range cnt {
ans += v - (v & 1)
if ans&1 == 0 && v&1 == 1 {
ans++
}
ans += v / 2 * 2
}
if ans < len(s) {
ans++
}
return
}
Expand All @@ -148,17 +143,13 @@ func longestPalindrome(s string) (ans int) {

```ts
function longestPalindrome(s: string): number {
let n = s.length;
let ans = 0;
let record = new Array(128).fill(0);
for (let i = 0; i < n; i++) {
record[s.charCodeAt(i)]++;
}
for (let i = 65; i < 128; i++) {
let count = record[i];
ans += count % 2 == 0 ? count : count - 1;
const cnt: Record<string, number> = {};
for (const c of s) {
cnt[c] = (cnt[c] || 0) + 1;
}
return ans < s.length ? ans + 1 : ans;
let ans = Object.values(cnt).reduce((acc, v) => acc + Math.floor(v / 2) * 2, 0);
ans += ans < s.length ? 1 : 0;
return ans;
}
```

Expand All @@ -169,52 +160,22 @@ use std::collections::HashMap;

impl Solution {
pub fn longest_palindrome(s: String) -> i32 {
let mut map: HashMap<char, i32> = HashMap::new();
for c in s.chars() {
map.insert(c, map.get(&c).unwrap_or(&0) + 1);
let mut cnt = HashMap::new();
for ch in s.chars() {
*cnt.entry(ch).or_insert(0) += 1;
}
let mut has_odd = false;
let mut res = 0;
for v in map.values() {
res += v;
if v % 2 == 1 {
has_odd = true;
res -= 1;
}
}
res + (if has_odd { 1 } else { 0 })
}
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- solution:start -->

### 方法二

<!-- tabs:start -->

#### TypeScript
let mut ans = 0;
for &v in cnt.values() {
ans += (v / 2) * 2;
}

```ts
function longestPalindrome(s: string): number {
const map = new Map();
for (const c of s) {
map.set(c, (map.get(c) ?? 0) + 1);
}
let hasOdd = false;
let res = 0;
for (const v of map.values()) {
res += v;
if (v & 1) {
hasOdd = true;
res--;
if ans < (s.len() as i32) {
ans += 1;
}

ans
}
return res + (hasOdd ? 1 : 0);
}
```

Expand Down
107 changes: 34 additions & 73 deletions solution/0400-0499/0409.Longest Palindrome/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ tags:

A valid palindrome string can have at most one character that appears an odd number of times, and the rest of the characters appear an even number of times.

Therefore, we can first traverse the string $s$, count the number of times each character appears, and record it in an array or hash table $cnt$.
Therefore, we can first traverse the string $s$, count the number of occurrences of each character, and record it in an array or hash table $cnt$.

Then, we traverse $cnt$, for each character $c$, if $cnt[c]$ is even, then directly add $cnt[c]$ to the answer $ans$; if $cnt[c]$ is odd, then add $cnt[c] - 1$ to $ans$, if $ans$ is even, then increase $ans$ by $1$.
Then, we traverse $cnt$, for each count $v$, we divide $v$ by 2, take the integer part, multiply by 2, and add it to the answer $ans$.

Finally, we return $ans$.
Finally, if the answer is less than the length of the string $s$, we increment the answer by one and return $ans$.

The time complexity is $O(n)$, and the space complexity is $O(C)$. Here, $n$ is the length of the string $s$; and $C$ is the size of the character set, in this problem $C = 128$.
The time complexity is $O(n + |\Sigma|)$, 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$.

<!-- tabs:start -->

Expand All @@ -73,10 +73,8 @@ The time complexity is $O(n)$, and the space complexity is $O(C)$. Here, $n$ is
class Solution:
def longestPalindrome(self, s: str) -> int:
cnt = Counter(s)
ans = 0
for v in cnt.values():
ans += v - (v & 1)
ans += (ans & 1 ^ 1) and (v & 1)
ans = sum(v // 2 * 2 for v in cnt.values())
ans += int(ans < len(s))
return ans
```

Expand All @@ -86,16 +84,15 @@ class Solution:
class Solution {
public int longestPalindrome(String s) {
int[] cnt = new int[128];
for (int i = 0; i < s.length(); ++i) {
int n = s.length();
for (int i = 0; i < n; ++i) {
++cnt[s.charAt(i)];
}
int ans = 0;
for (int v : cnt) {
ans += v - (v & 1);
if (ans % 2 == 0 && v % 2 == 1) {
++ans;
}
ans += v / 2 * 2;
}
ans += ans < n ? 1 : 0;
return ans;
}
}
Expand All @@ -108,16 +105,14 @@ class Solution {
public:
int longestPalindrome(string s) {
int cnt[128]{};
for (char& c : s) {
for (char c : s) {
++cnt[c];
}
int ans = 0;
for (int v : cnt) {
ans += v - (v & 1);
if (ans % 2 == 0 && v % 2 == 1) {
++ans;
}
ans += v / 2 * 2;
}
ans += ans < s.size();
return ans;
}
};
Expand All @@ -132,10 +127,10 @@ func longestPalindrome(s string) (ans int) {
cnt[c]++
}
for _, v := range cnt {
ans += v - (v & 1)
if ans&1 == 0 && v&1 == 1 {
ans++
}
ans += v / 2 * 2
}
if ans < len(s) {
ans++
}
return
}
Expand All @@ -145,17 +140,13 @@ func longestPalindrome(s string) (ans int) {

```ts
function longestPalindrome(s: string): number {
let n = s.length;
let ans = 0;
let record = new Array(128).fill(0);
for (let i = 0; i < n; i++) {
record[s.charCodeAt(i)]++;
}
for (let i = 65; i < 128; i++) {
let count = record[i];
ans += count % 2 == 0 ? count : count - 1;
const cnt: Record<string, number> = {};
for (const c of s) {
cnt[c] = (cnt[c] || 0) + 1;
}
return ans < s.length ? ans + 1 : ans;
let ans = Object.values(cnt).reduce((acc, v) => acc + Math.floor(v / 2) * 2, 0);
ans += ans < s.length ? 1 : 0;
return ans;
}
```

Expand All @@ -166,52 +157,22 @@ use std::collections::HashMap;

impl Solution {
pub fn longest_palindrome(s: String) -> i32 {
let mut map: HashMap<char, i32> = HashMap::new();
for c in s.chars() {
map.insert(c, map.get(&c).unwrap_or(&0) + 1);
let mut cnt = HashMap::new();
for ch in s.chars() {
*cnt.entry(ch).or_insert(0) += 1;
}
let mut has_odd = false;
let mut res = 0;
for v in map.values() {
res += v;
if v % 2 == 1 {
has_odd = true;
res -= 1;
}
}
res + (if has_odd { 1 } else { 0 })
}
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- solution:start -->

### Solution 2

<!-- tabs:start -->

#### TypeScript
let mut ans = 0;
for &v in cnt.values() {
ans += (v / 2) * 2;
}

```ts
function longestPalindrome(s: string): number {
const map = new Map();
for (const c of s) {
map.set(c, (map.get(c) ?? 0) + 1);
}
let hasOdd = false;
let res = 0;
for (const v of map.values()) {
res += v;
if (v & 1) {
hasOdd = true;
res--;
if ans < (s.len() as i32) {
ans += 1;
}

ans
}
return res + (hasOdd ? 1 : 0);
}
```

Expand Down
8 changes: 3 additions & 5 deletions solution/0400-0499/0409.Longest Palindrome/Solution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ class Solution {
public:
int longestPalindrome(string s) {
int cnt[128]{};
for (char& c : s) {
for (char c : s) {
++cnt[c];
}
int ans = 0;
for (int v : cnt) {
ans += v - (v & 1);
if (ans % 2 == 0 && v % 2 == 1) {
++ans;
}
ans += v / 2 * 2;
}
ans += ans < s.size();
return ans;
}
};
8 changes: 4 additions & 4 deletions solution/0400-0499/0409.Longest Palindrome/Solution.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ func longestPalindrome(s string) (ans int) {
cnt[c]++
}
for _, v := range cnt {
ans += v - (v & 1)
if ans&1 == 0 && v&1 == 1 {
ans++
}
ans += v / 2 * 2
}
if ans < len(s) {
ans++
}
return
}
Loading
Loading