leetcode-master/problems/1207.独一无二的出现次数.md

212 lines
6.5 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<p align="center">
<a href="https://programmercarl.com/other/xunlianying.html" target="_blank">
<img src="../pics/训练营.png" width="1000"/>
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 1207.独一无二的出现次数
[力扣题目链接](https://leetcode.cn/problems/unique-number-of-occurrences/)
给你一个整数数组 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
# 思路
这道题目数组在是哈希法中的经典应用,如果对数组在哈希法中的使用还不熟悉的同学可以看这两篇:[数组在哈希法中的应用](https://programmercarl.com/0242.有效的字母异位词.html)和[哈希法383. 赎金信](https://programmercarl.com/0383.赎金信.html)
进而可以学习一下[set在哈希法中的应用](https://programmercarl.com/0349.两个数组的交集.html),以及[map在哈希法中的应用](https://programmercarl.com/0001.两数之和.html)
回归本题,**本题强调了-1000 <= arr[i] <= 1000**那么就可以用数组来做哈希arr[i]作为哈希表数组的下标那么arr[i]可以是负数,怎么办?负数不能做数组下标。
**此时可以定义一个2000大小的数组例如int count[2002];**统计的时候将arr[i]统一加1000这样就可以统计arr[i]的出现频率了。
题目中要求的是是否有相同的频率出现那么需要再定义一个哈希表数组用来记录频率是否重复出现过bool fre[1002]; 定义布尔类型的就可以了,**因为题目中强调1 <= arr.length <= 1000所以哈希表大小为1000就可以了**。
如图所示:
<img src='https://code-thinking.cdn.bcebos.com/pics/1207.独一无二的出现次数.png' width=600> </img></div>
C++代码如下:
```CPP
class Solution {
public:
bool uniqueOccurrences(vector<int>& arr) {
int count[2002] = {0}; // 统计数字出现的频率
for (int i = 0; i < arr.size(); i++) {
count[arr[i] + 1000]++;
}
bool fre[1002] = {false}; // 看相同频率是否重复出现
for (int i = 0; i <= 2000; i++) {
if (count[i]) {
if (fre[count[i]] == false) fre[count[i]] = true;
else return false;
}
}
return true;
}
};
```
# 其他语言版本
Java
```java
class Solution {
public boolean uniqueOccurrences(int[] arr) {
int[] count = new int[2002];
for (int i = 0; i < arr.length; i++) {
count[arr[i] + 1000]++; // 防止负数作为下标
}
boolean[] flag = new boolean[1002]; // 标记相同频率是否重复出现
for (int i = 0; i <= 2000; i++) {
if (count[i] > 0) {
if (flag[count[i]] == false) {
flag[count[i]] = true;
} else {
return false;
}
}
}
return true;
}
}
```
Python
```python
# 方法 1: 数组在哈西法的应用
class Solution:
def uniqueOccurrences(self, arr: List[int]) -> bool:
count = [0] * 2002
for i in range(len(arr)):
count[arr[i] + 1000] += 1 # 防止负数作为下标
freq = [False] * 1002 # 标记相同频率是否重复出现
for i in range(2001):
if count[i] > 0:
if freq[count[i]] == False:
freq[count[i]] = True
else:
return False
return True
```
```python
# 方法 2 map 在哈西法的应用
class Solution:
def uniqueOccurrences(self, arr: List[int]) -> bool:
ref = dict()
for i in range(len(arr)):
ref[arr[i]] = ref.get(arr[i], 0) + 1
value_list = sorted(ref.values())
for i in range(len(value_list) - 1):
if value_list[i + 1] == value_list[i]:
return False
return True
```
Go
JavaScript
``` javascript
// 方法一:使用数组记录元素出现次数
var uniqueOccurrences = function(arr) {
const count = new Array(2002).fill(0);// -1000 <= arr[i] <= 1000
for(let i = 0; i < arr.length; i++){
count[arr[i] + 1000]++;// 防止负数作为下标
}
// 标记相同频率是否重复出现
const fre = new Array(1002).fill(false);// 1 <= arr.length <= 1000
for(let i = 0; i <= 2000; i++){
if(count[i] > 0){//有i出现过
if(fre[count[i]] === false) fre[count[i]] = true;//之前未出现过,标记为出现
else return false;//之前就出现了,重复出现
}
}
return true;
};
// 方法二使用Map 和 Set
/**
* @param {number[]} arr
* @return {boolean}
*/
var uniqueOccurrences = function(arr) {
// 记录每个元素出现次数
let map = new Map();
arr.forEach( x => {
map.set(x, (map.get(x) || 0) + 1);
})
// Set() 里的元素是不重复的。如果有元素出现次数相同则最后的set的长度不等于map的长度
return map.size === new Set(map.values()).size
};
```
TypeScript
> 借用数组:
```typescript
function uniqueOccurrences(arr: number[]): boolean {
const countArr: number[] = new Array(2001).fill(0);
for (let i = 0, length = arr.length; i < length; i++) {
countArr[arr[i] + 1000]++;
}
const flagArr: boolean[] = new Array(1001).fill(false);
for (let count of countArr) {
if (count === 0) continue;
if (flagArr[count] === true) return false;
flagArr[count] = true;
}
return true;
};
```
> 借用map、set
```typescript
function uniqueOccurrences(arr: number[]): boolean {
const countMap: Map<number, number> = new Map();
arr.forEach(val => {
countMap.set(val, (countMap.get(val) || 0) + 1);
})
return countMap.size === new Set(countMap.values()).size;
};
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>