Easy
题目描述
给定一个字符串 s,如果 s 是一个 好字符串,则返回 true,否则返回 false。
如果 s 中出现的所有字符的出现次数都相同(即频率相同),则字符串 s 是 好字符串。
示例 1:
输入: s = "abacbc"
输出: true
解释: s 中出现的字符是 'a'、'b' 和 'c'。所有字符在 s 中都出现 2 次。
示例 2:
输入: s = "aaabb"
输出: false
解释: s 中出现的字符是 'a' 和 'b'。
'a' 出现 3 次,'b' 出现 2 次,出现次数不相同。
约束:
1 <= s.length <= 1000s由小写英文字母组成。
提示:
- 建立一个字典,包含 s 中每个字符出现的频率
- 检查字典中的所有值是否相同
解题思路
这道题的核心思路是统计每个字符的出现次数,然后检查所有字符的频率是否相等。
解题思路
方法一:哈希表统计 + 频率比较(推荐)
- 使用哈希表(或数组)统计每个字符的出现次数
- 遍历哈希表中的所有频率值,检查是否都相等
- 可以取第一个字符的频率作为基准,然后比较其他字符的频率是否与基准相同
方法二:哈希表统计 + 集合去重
- 统计每个字符的出现次数
- 将所有频率值放入集合中去重
- 如果集合的大小为1,说明所有频率都相同
优化点:
- 由于只有小写英文字母,可以使用长度为26的数组代替哈希表
- 可以在统计过程中记录第一个非零频率,边统计边比较
时间复杂度为 O(n),空间复杂度为 O(1)(字符集大小固定)。
代码实现
class Solution {
public:
bool areOccurrencesEqual(string s) {
unordered_map<char, int> count;
for (char c : s) {
count[c]++;
}
int target = count.begin()->second;
for (auto& p : count) {
if (p.second != target) {
return false;
}
}
return true;
}
};
class Solution:
def areOccurrencesEqual(self, s: str) -> bool:
count = {}
for c in s:
count[c] = count.get(c, 0) + 1
target = next(iter(count.values()))
return all(freq == target for freq in count.values())
public class Solution {
public bool AreOccurrencesEqual(string s) {
var count = new Dictionary<char, int>();
foreach (char c in s) {
count[c] = count.GetValueOrDefault(c, 0) + 1;
}
int target = count.Values.First();
return count.Values.All(freq => freq == target);
}
}
/**
* @param {string} s
* @return {boolean}
*/
var areOccurrencesEqual = function(s) {
const freq = {};
for (let char of s) {
freq[char] = (freq[char] || 0) + 1;
}
const counts = Object.values(freq);
return counts.every(count => count === counts[0]);
};
复杂度分析
| 复杂度 | 大小 |
|---|---|
| 时间复杂度 | O(n),其中 n 是字符串长度,需要遍历字符串一次统计频率,再遍历频率表一次检查 |
| 空间复杂度 | O(1),最多需要存储26个小写字母的频率信息,空间使用量为常数级别 |
相关题目
. Rings and Rods (Easy)