剑指 Offer 03. 数组中重复的数字

目录

题目

解题思路1——暴力破解

解题思路2——利用散列表(哈希表)

题解——暴力破解

题解——哈希表


题目

找出数组中重复的数字。


在一个长度为 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;  //整个数组中没有一个是重复的
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值