题目描述

✅ 1207. 独一无二的出现次数

image-20260928233947009

题意分析

统计数组里每一种不同数值各出现多少次,再判断这些出现次数是否两两不同。只要两个不同的值具有相同次数,就返回 false;所有频次都不重复才返回 true。

元素值本身可以重复,也可以为负数;要去重比较的是最终次数,而不是原数组中的值。数组中只有一种数值时,无论它出现多少次,都不存在两个值频次相同的冲突。

解法:先按值计数,再对次数判重

核心思路

[!blue]

先用哈希表 count 把相同元素合并计数。第一阶段的键是元素值,值是这个元素在整个数组中的次数;必须完成全部统计后再比较,扫描过程中的临时次数还会继续变化,不能提前据此判定冲突。

再用集合 times 保存已经检查过的频次。逐个读取计数表的值,如果这个次数尚未见过就加入集合;如果已经存在,就找到了两个不同数值的相同最终次数,可以立即返回 false。

第一张表对每个数值只保留一个条目,所以第二阶段每次访问必然来自不同的数值。集合因此正好检测题目要排除的频次重复,而不会把同一个数值的多次出现当成多个冲突项。全部条目都能成功加入时,次数就两两不同。

解题步骤

  1. 扫描原数组,按数值累加次数。
  2. 创建空的频次集合,遍历计数表中每个不同值对应的最终次数。
  3. 某个次数已经出现时立即返回 false,否则登记它。
  4. 所有频次都没有重复,返回 true。

代码实现

class Solution {
    public boolean uniqueOccurrences(int[] arr) {
        Map<Integer, Integer> count = new HashMap<>();

        for (int num : arr) {
            // 第一阶段:按值计数,负数也能直接当键,不需要下标偏移。
            count.put(num, count.getOrDefault(num, 0) + 1);
        }

        Set<Integer> times = new HashSet<>();

        for (int c : count.values()) {
            // 遍历的是值(次数)而不是键;add 返回 false 说明这个次数已出现过。
            if (!times.add(c)) {
                return false;
            }
        }

        return true;
    }
}
func uniqueOccurrences(arr []int) bool {
    count := make(map[int]int)

    for _, num := range arr {
        // 第一阶段:map 的零值就是 0,可以直接自增。
        count[num]++
    }

    times := make(map[int]bool)

    for _, c := range count {
        // 先查再写:已经见过这个次数说明有两个值的出现次数相同。
        if times[c] {
            return false
        }
        times[c] = true
    }

    return true
}

复杂度分析

  • 时间复杂度:期望 $O(n)$,统计扫描 n 个元素,再检查不超过 n 个不同值的频次。
  • 空间复杂度:$O(u)$,u 为不同元素值的数量,次数表与频次集合各至多保存 u 项。

关键点总结

[!green]

  • 第一层按元素值聚合,第二层按最终次数判重,两个键的含义不同。
  • 先完整统计再判重,避免把还会增长的临时次数当作结论。
  • Java 集合添加失败或 Go 集合已包含该次数,都直接表示找到了重复频次。

易错点总结

[!yellow]

  • 直接判断原数组有没有重复元素,回答了与题目不同的问题。
  • 遍历计数表的键来去重,键本来就不同,无法检查频次冲突。
  • 还未统计完整数组就因临时频次相等返回失败,后续出现可能会让最终次数不同。
  • 把同一个数值的每次出现都放入频次集合,会重复检查同一条统计记录。
  • 直接用原值索引没有处理负数范围的数组,可能越界;哈希键可以直接保存负数。

相似题目

题目 难度 关联与区别
1657. 确定两个字符串是否接近 中等 同样把字符频次作为另一层数据,本题要求频次互异,原题比较两串频次多重集合。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2026/41712206
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!