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
}

二、算法分析

  1. 核心思路

    • 哈希表统计:使用哈希表记录每个元素的出现次数
    • 集合去重:通过集合检查频率是否唯一
    • 双重验证:先统计词频,再验证词频唯一性
  2. 关键步骤

    • 频率统计:遍历数组,用哈希表记录每个数字出现次数(时间复杂度 O(n))
    • 唯一性验证:将哈希表的值存入集合,通过集合自动去重特性判断是否有重复频率(时间复杂度 O(m),m 为不同数字数量)
    • 极值判断:发现重复频率时立即返回 false,否则遍历完成后返回 true
  3. 复杂度

    指标 说明
    时间复杂度 O(n) 两次线性遍历(n 为数组长度)
    空间复杂度 O(n) 存储哈希表和集合

三、图解示例

LeetCode算法题(Go语言实现)_21_第1张图片

四、边界条件与扩展

  1. 特殊场景处理

    • 全唯一元素[1,2,3] → 所有频率为1,返回 false
    • 单个元素[5] → 频率为1,返回 true
    • 超大数值范围:哈希表自动处理离散分布
  2. 多语言实现

# 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();
}
  1. 算法对比
方法 时间复杂度 空间复杂度 优势
哈希表+集合法 O(n) O(n) 最优解,代码简洁
排序+遍历法 O(n log n) O(1) 无需额外空间
双重循环法 O(n²) O(1) 仅适用于极小数据量

五、总结与扩展

  • 数学本质:集合论中的单射关系验证(频率集合与原集合大小相等)
  • 工程优化:利用哈希表与集合的 O(1) 查询特性实现高效判断
  • 扩展应用
    1. 词频分析:验证文本中单词出现次数的唯一性
    2. 数据校验:检测日志中事件发生次数的唯一性
    3. 流式处理:结合布隆过滤器处理大规模数据流

你可能感兴趣的:(LeetCode,算法,leetcode,职场和发展,golang)