拓冰建站拓冰建站
首页 / 资讯中心 / 正文

LeetCode-Go 题解:1207. Unique Number of Occurrences 唯一出现次数判断

LeetCode-Go 题解1207. Unique Number of Occurrences 唯一出现次数判断【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go导读本篇围绕 LeetCode 第 1207 题「Unique Number of Occurrences唯一出现次数」展开以 LeetCode-Go 仓库中该题目的 README 为骨架结合其 Go 实现与测试用例进行源码级剖析。读完本文你将掌握统计频次 判重这一经典双哈希表套路理解本仓库 1207 题的官方解法 的时间/空间复杂度并能通过仓库自带的测试代码独立验证结论。题目描述Given an array of integersarr, write a function that returnstrueif and only if the number of occurrences of each value in the array is unique.给定一个整数数组arr统计数组中每个数值出现的次数只有当数组中每个数值的出现次数都互不相同时函数才返回true否则返回false。示例示例 1Input: arr [1,2,2,1,1,3] Output: true解释数值 1 出现 3 次数值 2 出现 2 次数值 3 出现 1 次。三个出现次数3、2、1互不相同因此返回true。示例 2Input: arr [1,2] Output: false解释数值 1 和数值 2 各出现 1 次出现次数重复都为 1因此返回false。示例 3Input: arr [-3,0,1,-3,1,1,1,-3,10,0] Output: true解释数组长度为 10各数值出现次数为-3 出现 3 次、0 出现 2 次、1 出现 4 次、10 出现 1 次互不相同返回true。数据约束1 arr.length 1000-1000 arr[i] 1000约束意味着数组非空、长度不超过 1000元素取值落在[-1000, 1000]的闭区间内。由于每个数值最多出现arr.length次频次的最大可能值也是 1000因此频次本身可以用普通int安全存储不存在溢出问题。解题思路这是一道典型的哈希表计数入门题核心思路分两步统计频次遍历数组用一张哈希表map记录每个数值出现的次数频次判重遍历频次表用另一张哈希表记录哪些频次已经出现过一旦发现某个频次重复出现立即返回false全部不重复则返回true。之所以需要两张哈希表是因为问题同时要求「值 → 频次」和「频次是否唯一」两类信息第一张表完成聚合统计第二张表完成唯一性校验职责分离、逻辑清晰。仓库源码实现解析仓库中 1207 题的 Go 实现 完整代码如下package leetcode func uniqueOccurrences(arr []int) bool { freq, m : map[int]int{}, map[int]bool{} for _, v : range arr { freq[v] } for _, v : range freq { if _, ok : m[v]; !ok { m[v] true } else { return false } } return true }逐行解读freq, m : map[int]int{}, map[int]bool{}同时声明两张哈希表。freq的键是数组元素的值、值是出现次数m的键是频次、值是布尔标记充当频次集合。第一个for range循环完成频次统计freq[v]对map中不存在的键自动初始化为零值0再加一等价于先取值、加一、再写回是 Go 语言map计数的惯用写法。第二个for range循环遍历freq的所有键值对v为频次。采用if _, ok : m[v]; !ok的「逗号 ok」惯用法判断频次是否已存在不存在!ok标记为已出现已存在ok说明有两个不同的数值拥有相同出现次数直接return false。循环正常结束意味着所有频次唯一返回true。复杂度分析时间复杂度O(n)其中n arr.length。第一遍遍历数组统计频次为O(n)第二遍遍历频次表最多为O(n)去重后键的数量不超过 n整体线性。空间复杂度O(n)。两张哈希表在最坏情况下每个元素都不同各需存储 n 个条目。实现细节上的两个可优化点从代码结构看该实现有以下两个值得注意的设计取舍提前返回第二遍遍历在发现重复频次时立即return false无需处理完整个频次表在大概率不满足条件的输入上可以提前结束判重写法的简化空间其实判重逻辑可进一步缩写为if m[v] { return false }; m[v] true。仓库保留显式的_, ok写法语义更直白也更贴近 Go 官方 Code Review 注释中推崇的可读性风格仓库 README 明确声明代码风格遵循 Google Golang Style Guide。测试用例与验证仓库为每题配套了表驱动风格的测试文件1207 题的测试代码 结构如下package leetcode import ( fmt testing ) type question1207 struct { para1207 ans1207 } // para 是参数 // one 代表第一个参数 type para1207 struct { arr []int } // ans 是答案 // one 代表第一个答案 type ans1207 struct { one bool } func Test_Problem1207(t *testing.T) { qs : []question1207{ { para1207{[]int{1, 2, 2, 1, 1, 3}}, ans1207{true}, }, { para1207{[]int{1, 2}}, ans1207{false}, }, { para1207{[]int{-3, 0, 1, -3, 1, 1, 1, -3, 10, 0}}, ans1207{true}, }, } fmt.Printf(------------------------Leetcode Problem 1207------------------------\n) for _, q : range qs { _, p : q.ans1207, q.para1207 fmt.Printf(【input】:%v 【output】:%v\n, p, uniqueOccurrences(p.arr)) } fmt.Printf(\n\n\n) }该测试覆盖了题目给出的全部三个示例true的正例示例 1、示例 3含负数和 0 的场景与false的反例示例 2。测试采用question1207结构体将输入参数para1207与期望答案ans1207捆绑是 LeetCode-Go 仓库统一使用的表驱动测试约定。仓库通过 gotest.sh 执行全量测试与覆盖率采集go test -covermodeatomic -coverprofilecoverage.txt ./leetcode/...在leetcode/目录下运行该命令即可连同本题一起执行测试生成的coverage.txt可用于覆盖率统计仓库项目描述中声明整体覆盖率为 100%。若只想单独验证本题可运行go test -v -run Test_Problem1207 ./leetcode/1207.Unique-Number-of-Occurrences/仓库使用 Go 1.19见 go.mod并提供了structures、template等本地模块的replace指令属于单模块 本地子模块的组织方式直接在本仓库根目录执行go test即可完成验证。同类解法的横向对比除仓库采用的双哈希表方案外本题还有几种常见的等价实现理解它们有助于加深对判重问题的认识。方案一频次集合长度比较统计完频次后将所有频次放入一个set比较set的大小与频次总数是否相等func uniqueOccurrences(arr []int) bool { freq : map[int]int{} for _, v : range arr { freq[v] } seen : map[int]bool{} for _, c : range freq { seen[c] true } return len(seen) len(freq) }其本质与仓库解法完全一致len(seen) len(freq)成立当且仅当频次无重复。该写法更函数式但无法提前返回需要完整遍历两轮仓库实现则利用提前返回在多数场景下更快。方案二排序后相邻比较将频次收集到切片后排序再检查相邻元素是否相等import sort func uniqueOccurrences(arr []int) bool { freq : map[int]int{} for _, v : range arr { freq[v] } cs : make([]int, 0, len(freq)) for _, c : range freq { cs append(cs, c) } sort.Ints(cs) for i : 1; i len(cs); i { if cs[i] cs[i-1] { return false } } return true }该方案时间复杂度退化为O(n log n)空间复杂度仍为O(n)。在n 1000的约束下性能差异可忽略但哈希表方案在原理上更优这也是仓库选择双哈希表的原因。方案三结合数据约束的定长数组优化注意到约束-1000 arr[i] 1000数组元素值域只有 2001 种可能因此可用定长数组替代map统计频次元素值 1000 映射到下标 02000再用另一个定长数组标记频次是否出现过。该方案将哈希的常数开销替换为连续内存访问且空间复杂度可视为O(2001)的常数级在极端追求性能的场景如竞赛下是常见优化但可读性略逊且当约束放宽时需同步调整数组大小。总结LeetCode 1207「Unique Number of Occurrences」是一道简洁而典型的哈希表应用题先以map完成值 → 频次的聚合再以第二张map完成频次唯一性校验整体时间复杂度O(n)、空间复杂度O(n)。仓库实现通过逗号 ok惯用法与提前返回保持了代码的清晰与高效配套测试覆盖了题目的全部官方示例可直接运行 gotest.sh 验证。掌握这道题的双哈希表思想对后续处理「频次统计 去重判重」类问题如 451. Sort Characters By Frequency、347. Top K Frequent Elements具有直接的迁移价值。参考资料题目官方描述与示例leetcode.com仓库 READMELeetCode-Go 总览1207 题 Go 源码1207 题测试源码1207 题解题文档本仓库 README覆盖率测试脚本【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门