47
47
48
48
<!-- 这里可写通用的实现逻辑 -->
49
49
50
- > 一个回文字符串,最多存在一个出现奇数次数的字符,
50
+ ** 方法一:计数 **
51
51
52
- 先统计所有字符出现的次数,通用的方式是哈希表。题目已说明只存在大小写字母(52 种可能),也可以使用数组来存储 。
52
+ 一个合法的回文字符串,最多存在一个出现奇数次数的字符,其余字符出现次数均为偶数 。
53
53
54
- 而后,可分两种方式:
54
+ 因此,我们可以先遍历字符串 $s$,统计每个字符出现的次数,记录在数组或哈希表 $cnt$ 中。
55
55
56
- - 布尔变量
57
- - 累加出现次数为偶数的数值。
58
- - 对于奇数,第一次出现,完整累加;后续出现,则需要对次数 ` -1 ` 去奇,再累加。
59
- - 计数器
60
- - 记录奇数出现的次数,最后的结果回文长度由 ` s.length - count ` 得知。
61
- - 如果只存在一个奇数,那么可以直接返回 ` s.length ` .
56
+ 然后,我们遍历 $cnt$,对于每个字符 $c$,如果 $cnt[ c] $ 为偶数,则直接将 $cnt[ c] $ 累加到答案 $ans$ 中;如果 $cnt[ c] $ 为奇数,则将 $cnt[ c] - 1$ 累加到 $ans$ 中,如果 $ans$ 为偶数,则将 $ans$ 增加 $1$。
57
+
58
+ 最后,我们返回 $ans$ 即可。
59
+
60
+ 时间复杂度 $O(n)$,空间复杂度 $O(C)$。其中 $n$ 为字符串 $s$ 的长度;而 $C$ 为字符集的大小,本题中 $C = 128$。
62
61
63
62
<!-- tabs:start -->
64
63
69
68
``` python
70
69
class Solution :
71
70
def longestPalindrome (self , s : str ) -> int :
72
- n = len (s)
73
- counter = Counter(s)
74
- odd_cnt = sum (e % 2 for e in counter.values())
75
- return n if odd_cnt == 0 else n - odd_cnt + 1
71
+ cnt = Counter(s)
72
+ ans = 0
73
+ for v in cnt.values():
74
+ ans += v - (v & 1 )
75
+ ans += (ans & 1 ^ 1 ) and (v & 1 )
76
+ return ans
76
77
```
77
78
78
79
### ** Java**
@@ -82,20 +83,62 @@ class Solution:
82
83
``` java
83
84
class Solution {
84
85
public int longestPalindrome (String s ) {
85
- int [] counter = new int [128 ];
86
- for (char c : s . toCharArray() ) {
87
- ++ counter[c ];
86
+ int [] cnt = new int [128 ];
87
+ for (int i = 0 ; i < s . length(); ++ i ) {
88
+ ++ cnt[s . charAt(i) ];
88
89
}
89
- int oddCnt = 0 ;
90
- for (int e : counter) {
91
- oddCnt += (e % 2 );
90
+ int ans = 0 ;
91
+ for (int v : cnt) {
92
+ ans += v - (v & 1 );
93
+ if (ans % 2 == 0 && v % 2 == 1 ) {
94
+ ++ ans;
95
+ }
92
96
}
93
- int n = s. length();
94
- return oddCnt == 0 ? n : n - oddCnt + 1 ;
97
+ return ans;
95
98
}
96
99
}
97
100
```
98
101
102
+ ### ** C++**
103
+
104
+ ``` cpp
105
+ class Solution {
106
+ public:
107
+ int longestPalindrome(string s) {
108
+ int cnt[ 128] {};
109
+ for (char& c : s) {
110
+ ++cnt[ c] ;
111
+ }
112
+ int ans = 0;
113
+ for (int v : cnt) {
114
+ ans += v - (v & 1);
115
+ if (ans % 2 == 0 && v % 2 == 1) {
116
+ ++ans;
117
+ }
118
+ }
119
+ return ans;
120
+ }
121
+ };
122
+ ```
123
+
124
+ ### **Go**
125
+
126
+ ```go
127
+ func longestPalindrome(s string) (ans int) {
128
+ cnt := [128]int{}
129
+ for _, c := range s {
130
+ cnt[c]++
131
+ }
132
+ for _, v := range cnt {
133
+ ans += v - (v & 1)
134
+ if ans&1 == 0 && v&1 == 1 {
135
+ ans++
136
+ }
137
+ }
138
+ return
139
+ }
140
+ ```
141
+
99
142
### ** TypeScript**
100
143
101
144
``` ts
@@ -133,42 +176,6 @@ function longestPalindrome(s: string): number {
133
176
}
134
177
```
135
178
136
- ### ** C++**
137
-
138
- ``` cpp
139
- class Solution {
140
- public:
141
- int longestPalindrome(string s) {
142
- vector<int > counter(128);
143
- for (char c : s) ++counter[ c] ;
144
- int oddCnt = 0;
145
- for (int e : counter) oddCnt += e % 2;
146
- int n = s.size();
147
- return oddCnt == 0 ? n : n - oddCnt + 1;
148
- }
149
- };
150
- ```
151
-
152
- ### **Go**
153
-
154
- ```go
155
- func longestPalindrome(s string) int {
156
- counter := make([]int, 128)
157
- for _, c := range s {
158
- counter[c]++
159
- }
160
- oddCnt := 0
161
- for _, e := range counter {
162
- oddCnt += e % 2
163
- }
164
- n := len(s)
165
- if oddCnt == 0 {
166
- return n
167
- }
168
- return n - oddCnt + 1
169
- }
170
- ```
171
-
172
179
### ** Rust**
173
180
174
181
``` rust
0 commit comments