给你一个由小写英文字母组成的字符串 s。 请你找出字符串中两个字符 a1 和 a2 的出现频次之间的 最大 差值 diff = freq(a1) - freq(a2),这两个字符需要满足: a1 在字符串中出现 奇数次 。 a2 在字符串中出现 偶数次 。 返回 最大 差值。
示例 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 至少由一个出现奇数次的字符和一个出现偶数次的字符组成。
这是一道“字符串字符频次统计+极值筛选”的编程题,以下是其解法解析:
一、核心解题思路
要得到“奇数次频次 - 偶数次频次”的最大差值,需完成两个关键步骤:
1. 统计字符频次:用数组记录每个小写字母的出现次数(26个小写字母对应长度为26的数组); 2. 筛选目标极值:要让差值最大,需选取最大的奇数次频次(作为被减数)和最小的偶数次频次(作为减数); 3. 边界处理:若不存在奇数次/偶数次频次,返回-1。
二、代码逻辑拆解
cpp
int maxDifference(string s) { vector count(26, 0); // 1. 统计每个字符的出现次数 for (char c : s) { count[c - 'a']++; // 字符转数组索引(a→0,b→1...) }
int maxOdd = -1, minEven = INT_MAX;
// 2. 筛选最大奇数次、最小偶数次
for (int num : count) {
if (num == 0) continue; // 跳过未出现的字符
if (num % 2 == 1) { // 奇数次
maxOdd = max(maxOdd, num);
} else { // 偶数次
minEven = min(minEven, num);
}
}
// 3. 边界处理:无奇数/偶数频次时返回-1
if (maxOdd == -1 || minEven == INT_MAX) {
return -1;
}
return maxOdd - minEven; // 计算最大差值
}
三、示例验证
以示例1(输入 s = "aaaaabc" )为例:
字符频次: a→5(奇)、b→2(偶)、c→1(奇) ; 筛选结果: maxOdd=5 (最大奇数次)、 minEven=2 (最小偶数次); 差值: 5-2=3 ,与示例输出一致。
四、复杂度分析
时间复杂度: O(n) ( n 为字符串长度),仅需遍历字符串1次、遍历频次数组1次(26为常数); 空间复杂度: O(1) ,仅用了固定大小的数组(26个int),无额外动态空间开销。