LeetCode算法题(Go语言实现)_21
题目
给你一个整数数组 arr,如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false。
一、代码实现
func uniqueOccurrences(arr []int) bool {
freq := make(map[int]int)
// 统计每个数字的出现次数
for _, num := range arr {
freq[num]++
}
// 检查频率是否唯一
seen := make(map[int]bool)
for _, count := range freq {
if seen[count] {
return false
}
seen[count] = true
}
return true
}
二、算法分析
-
核心思路
- 哈希表统计:使用哈希表记录每个元素的出现次数
- 集合去重:通过集合检查频率是否唯一
- 双重验证:先统计词频,再验证词频唯一性
-
关键步骤
- 频率统计:遍历数组,用哈希表记录每个数字出现次数(时间复杂度 O(n))
- 唯一性验证:将哈希表的值存入集合,通过集合自动去重特性判断是否有重复频率(时间复杂度 O(m),m 为不同数字数量)
- 极值判断:发现重复频率时立即返回 false,否则遍历完成后返回 true
-
复杂度
指标 值 说明 时间复杂度 O(n) 两次线性遍历(n 为数组长度) 空间复杂度 O(n) 存储哈希表和集合
三、图解示例
四、边界条件与扩展
-
特殊场景处理
- 全唯一元素:
[1,2,3]
→ 所有频率为1,返回 false - 单个元素:
[5]
→ 频率为1,返回 true - 超大数值范围:哈希表自动处理离散分布
- 全唯一元素:
-
多语言实现
# Python实现(集合去重)
def uniqueOccurrences(arr):
from collections import Counter
freq = Counter(arr)
return len(freq.values()) == len(set(freq.values()))
// Java实现(两次哈希验证)
public boolean uniqueOccurrences(int[] arr) {
Map<Integer, Integer> freq = new HashMap<>();
for (int num : arr) freq.put(num, freq.getOrDefault(num, 0) + 1);
Set<Integer> set = new HashSet<>(freq.values());
return set.size() == freq.size();
}
- 算法对比
方法 | 时间复杂度 | 空间复杂度 | 优势 |
---|---|---|---|
哈希表+集合法 | O(n) | O(n) | 最优解,代码简洁 |
排序+遍历法 | O(n log n) | O(1) | 无需额外空间 |
双重循环法 | O(n²) | O(1) | 仅适用于极小数据量 |
五、总结与扩展
- 数学本质:集合论中的单射关系验证(频率集合与原集合大小相等)
- 工程优化:利用哈希表与集合的 O(1) 查询特性实现高效判断
- 扩展应用:
- 词频分析:验证文本中单词出现次数的唯一性
- 数据校验:检测日志中事件发生次数的唯一性
- 流式处理:结合布隆过滤器处理大规模数据流