题目描述
给你一个由小写英文字母组成的字符串 s
。请你找出字符串中两个字符的出现频次之间的 最大 差值,这两个字符需要满足:
- 一个字符在字符串中出现 偶数次 。
- 另一个字符在字符串中出现 奇数次 。
返回 最大 差值,计算方法是出现 奇数次 字符的次数 减去 出现 偶数次 字符的次数。
示例 1:
输入:s = "aaaaabbc"
输出:3
解释:
- 字符
'a'
出现 奇数次 ,次数为 5
;字符 'b'
出现 偶数次 ,次数为 2
。
- 最大差值为
5 - 2 = 3
。
示例 2:
输入:s = "abcabcab"
输出:1
解释:
- 字符
'a'
出现 奇数次 ,次数为 3
;字符 'c'
出现 偶数次 ,次数为 2 。
- 最大差值为
3 - 2 = 1
。
提示:
3 <= s.length <= 100
s
仅由小写英文字母组成。
s
至少由一个出现奇数次的字符和一个出现偶数次的字符组成。
解法
方法一:计数
我们可以用一个哈希表或数组 $\textit{cnt}$ 记录字符串 $s$ 中每个字符的出现次数。然后遍历 $\textit{cnt}$,找出出现奇数次的字符的最大频次 $a$ 和出现偶数次的字符的最小频次 $b$,最后返回 $a - b$ 即可。
时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 是字符集,本题中 $|\Sigma| = 26$。
| class Solution:
def maxDifference(self, s: str) -> int:
cnt = Counter(s)
a, b = 0, inf
for v in cnt.values():
if v % 2:
a = max(a, v)
else:
b = min(b, v)
return a - b
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution {
public int maxDifference(String s) {
int[] cnt = new int[26];
for (char c : s.toCharArray()) {
++cnt[c - 'a'];
}
int a = 0, b = 1 << 30;
for (int v : cnt) {
if (v % 2 == 1) {
a = Math.max(a, v);
} else if (v > 0) {
b = Math.min(b, v);
}
}
return a - b;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | class Solution {
public:
int maxDifference(string s) {
int cnt[26]{};
for (char c : s) {
++cnt[c - 'a'];
}
int a = 0, b = 1 << 30;
for (int v : cnt) {
if (v % 2 == 1) {
a = max(a, v);
} else if (v > 0) {
b = min(b, v);
}
}
return a - b;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | func maxDifference(s string) int {
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
}
a, b := 0, 1<<30
for _, v := range cnt {
if v%2 == 1 {
a = max(a, v)
} else if v > 0 {
b = min(b, v)
}
}
return a - b
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | function maxDifference(s: string): number {
const cnt: Record<string, number> = {};
for (const c of s) {
cnt[c] = (cnt[c] || 0) + 1;
}
let [a, b] = [0, Infinity];
for (const [_, v] of Object.entries(cnt)) {
if (v % 2 === 1) {
a = Math.max(a, v);
} else {
b = Math.min(b, v);
}
}
return a - b;
}
|