[剑指offer]数组中重复的数字

[剑指offer]数组中重复的数字

题目描述:

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3

限制:

2 <= n <= 100000

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的解法(Set方法):

class Solution {
    public int findRepeatNumber(int[] nums) {
        HashSet<Integer> set = new HashSet<>();
        for(int num:nums){
            if(set.contains(num)){
                return num;
            }else {
                set.add(num);
            }

        }
        return 0;
    }

}

在这里插入图片描述
很一般吧。
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3

我研究了下示例代码:

class Solution {
    public int findRepeatNumber(int[] nums) {
        int i = 0;
        while(i < nums.length){
            if(nums[i] == i){
                i++;
                continue;
            }
            if(nums[nums[i]] == nums[i]) return nums[i];
            int tmp = nums[nums[i]];
            nums[nums[i]] = nums[i];
            nums[i] = tmp;
        }
        return -1;
    }
}

在这里插入图片描述

然后我突然明白一个事实,我其实是用了一个通用解法,而示例代码实际上属于扣题了。
题目说了,在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。
于是它先将它排序。

初始:[2, 3, 1, 0, 2, 5, 3]
后续:在这里插入图片描述
用通俗的话来说这个逻辑就是:

判断当前的数是否在它应该在的位置,例如2就应该在nums[2]上,
如果不在这个位置上,就再去判断它和它应该在的那个位置上的数是否相等,
不相等则交换,然后循环。
这个方法很眼熟,一下子叫不出名字,数据结构应该学过这个。

看到一个更简单的,算是完美利用了题目:

class Solution {
    public int findRepeatNumber(int[] nums) {
        int[] arr = new int[nums.length];
        for(int i = 0; i < nums.length; i++){
            arr[nums[i]]++;
            if(arr[nums[i]] > 1) return nums[i];
        }
        return -1;
    }
}

他直接就用标记的方法,例如你这个[2, 3, 1, 0, 2, 5, 3]
第一个是2,那就这样标记[0010000]
第二个是3,那就变成这样[0011000]
在这里插入图片描述
当最后出现2的时候,便可以输出三了。
很巧妙。
在这里插入图片描述
其他是他和第二个方法用的都是同一种方法,只是第三种方法的写法比较巧妙,所以两者之间的开销其实是基本一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值