题目描述
给你一个整数数组 arr,请你帮忙统计数组中每个数的出现次数。
如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false
示例1:
输入:arr = [1,2,2,1,1,3]
输出:true
解释:在该数组中,1 出现了 3 次,2 出现了 2 次,3 只出现了 1 次。没有两个数的出现次数相同。
示例2:
输入:arr = [1,2]
输出:false
示例3:
输入:arr = [-3,0,1,-3,1,1,1,-3,10,0]
输出:true
提示:
1 <= arr.length <= 1000
-1000 <= arr[i] <= 1000
方法一、使用python字典存储次数
先存储次数,再存储次数的次数,最后判断次数如果大于等于二说明不唯一。否则输出True。i,j,k是每个循环里面的循环变量。
Python解法
class Solution(object):
def uniqueOccurrences(self, arr):
dic = {}
for i in arr:
if i not in dic:
dic[i] = 1
else:
dic[i] += 1
res = {}
for j in dic:
if dic[j] not in res:
res[dic[j]] = 1
else:#其实这里次数已经不唯一了
res[dic[j]] += 1
for k in res:
if res[k] >= 2:
return False
return True
耗时20ms
稍微优化一下,既然次数已经大于二了,我们就直接返回False,如果没有返回False,最后返回True
class Solution(object):
def uniqueOccurrences(self, arr):
a = {}
for i in arr:
if i not in a:
a[i] = 1
else:
a[i] += 1
b= {}
for j in a:
if a[j] in b:#次数不唯一
return False
else:
b[a[j]] = 1
return True
耗时16ms
方法二、Map
第一步都是要先计算每个数出现的次数。后面的只需要判断这个出现次数的数组中元素是否有重复的即可。
我们知道集合set是不能有重复元素的,如果有就会替换掉,我们可以把出现次数的数组放到集合set中,如果有重复的就会被替换掉,那么set的大小肯定和出现次数的数组长度不一样。否则如果没有重复的,他们的长度肯定是一样的,看下代码
补充知识
map.put方法:给map添加元素
map.getOrDefault方法:当Map集合中有这个key时,就使用这个key值,如果没有就使用默认值defaultValue
map.size()返回集合的元素条数,类似于python中列表的count方法
map.values() 方法用来获取 Map 集合中的所有键值对象,这些键值对象将存放在另一个集合对象中。
HashSet实际上是HashMap的实例化。
Java解法
public boolean uniqueOccurrences(int[] arr) {
//创建Map对象,采用哈希表结构
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);
}
return map.size() == new HashSet<>(map.values()).size();
}
耗时2ms
比如:arr = [1,2,2,1,1,3]
map.put(1,1)
map.put(2,1)
map.put(2,2)
map.put(1,2)
map.put(1,3)
map.put(3,1)
此时map包含{(1,3),(2,2),(3,1)}
map的大小与map的值组成的set集的大小相等。
参考
https://leetcode-cn.com/problems/unique-number-of-occurrences/solution/3chong-jie-jue-fang-shi-by-sdwwld-3/
Map.getOrDefault()方法
博主比较小白,但是热爱分享。一直感觉自己写代码的能力,算法能力都不太行,所以最近开始刷LeetCode,一方面记录方便自己学习,另一方面给需要的同伴参考。虽然失败并不可怕,但是也希望同伴们少踩一些坑。分析算法挺费劲的,留个赞或评论支持一下博主吧!同时我也非常希望写出更通俗易懂的文章,知识尚浅,如有遗漏或错误,欢迎指正~