【力扣刷题】1207. 独一无二的出现次数

462 阅读2分钟

「这是我参与11月更文挑战的第 23 天,活动详情查看:2021最后一次更文挑战

原题链接

1207. 独一无二的出现次数 - 力扣(LeetCode) (leetcode-cn.com)

题目描述

给你一个整数数组 arr,请你帮忙统计数组中每个数的出现次数。

如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false

测试用例

示例 1:

输入:arr = [1,2,2,1,1,3]
输出:true
解释:在该数组中,1 出现了 3 次,2 出现了 2 次,3 只出现了 1 次。没有两个数的出现次数相同。

示例 2:

输入:arr = [1,2]
输出:false

参数限制

  • 1 <= arr.length <= 1000
  • -1000 <= arr[i] <= 1000

分析

题目描述非常清晰,需要我们先统计各个数字出现的次数,统计完成后,再判断他们的次数是否存在重复项

代码

  1. 使用 Object 对象,在遍历数组的时候,统计各个数字的出现次数
  2. 使用 Object 对象内置的 .values 属性获取获取全部的统计次数
  3. 使用 Set 对象的特性来去除重复项,然后将转化为 set 之前的长度,与转化之后的长度相比,长度一致则表明不存在重复项;如长度不等,则说明有重复项被提出了,需要返回 false
var uniqueOccurrences = function(arr) {
    let obj = {};
    arr.forEach(n => {
        let count = obj[n] || 0;
        obj[n] = count + 1;
    })
    return Object.keys(obj).length == new Set(Object.values(obj)).size;
};

image.png

为什么需要 Set

先给出结论,Set 中的数据查找耗时是常量级的,而数组数组是线性级别的

网上对 JS 的 Set 底层源码的解释较少,没有发现;因为各个语言的标准数据结构的定义都是相通的,我就以 Java 中的 Set 为例

数组是一系列相邻的元素,我们如果需要在上面去查找某个数据,最差的情况就是需要遍历整个数组,然后在最后一位找到我们需要的数据

但是,如果切换为 Set 结构,Set 虽然也是使用数组辅助存储数据,但是,数据存储的下标确有讲究,我们可以根据这个数据去生成一个不变的 hash 值,然后使用 hash 值对应的数组下标来存储,这样就能很快定位到数据;如果对应的 hash 其他元素也会生成,即重码了,我们在数组对应的位置使用链表来扩充存储重复的数据,这样速度可能会慢一点,但仍会优于数组的顺序查找,这种情况叫 哈希碰撞,一个设计优秀的 Set 结构会出现较少的 哈希碰撞


今天的力扣刷题就分享到这里,感谢大家的阅读~