目录
题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 1:
输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3
限制:
2 <= n <= 100000
解题思路1——暴力破解
在一个数组中寻找重复值,如果题目中没有硬性要求算法的时间复杂度和空间复杂度,那么双重循环的暴力破解永远是一个可以得到正确答案的做法。
对于暴力破解的思路,这边便不再过多赘述,相信这是实现起来最简单的方法。
解题思路2——利用散列表(哈希表)
首先需要知道的是,什么是哈希表。
散列表(Hash table),又称为哈希表,该表根据键码值(Key value)进行访问。
键码值可以根据一个函数得出,它表示的是一种映射关系,就像这样:
Key value = Key mod 某一个值N = H(Key)
那么,该函数所得到的结果便一定会落在[0,N-1]的范围内。
当然,如果这个N十分的小而元素十分的多,那么,计算这些元素的键码值便可能会得到很多相同的值,而具有相同键码值的位置便发生了冲突。
哈希表的运转就像这样:
那么,哈希表便十分适合这一题了。
由于题目中明确说明了数组中所有元素的范围都在[0,n-1],那么,使用一张长度为n的哈希表,选用H(Key) = Key mod n,便可以很快捷地解决此题。
由于得到的哈希值必定会落在[0,n-1]的区间内,因此,初始时令哈希表中所有的元素都为0,当某一个元素首次落在哈希表的某一个位置时,将哈希表该位置的值增加1,这样一来,当哈希值发生冲突时,便可以直接返回发生哈希值冲突的元素。
当然,题目中只要找出一个重复的元素即可,若是需要找出所有重复的元素,那么哈希表也是可以完全胜任的。
题解——暴力破解
class Solution {
public int findRepeatNumber(int[] nums) {
int count = -1;
for(int i=0;i<nums.length;i++){
count = -1;
for(int j=0;j<nums.length;j++){
if(nums[i] == nums[j]){
count++;
}
}
if(count > 0){
return nums[i];
}
}
return -1;
}
}
但是需要注意的是,暴力破解法可以通过所有的测试用例但是运行时间可能会超出限制。
题解——哈希表
class Solution {
public int findRepeatNumber(int[] nums) {
int[] HashTable = new int[nums.length]; //哈希表
int HashCode = 0;
for(int i=0;i<nums.length;i++){
HashCode = nums[i] % nums.length; //计算哈希值
if(HashTable[HashCode] == 0){
//尚未重复
HashTable[HashCode] = 1;
}else{
//遇到重复
return nums[i];
}
}
return -1; //整个数组中没有一个是重复的
}
}