leetcode面试题03:数组中重复的数字

找出数组中重复的数字。

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

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

限制:
2 <= n <= 100000
审题:所有数字都在0~n-1的范围内!!!

思路:

我们注意到数组中的数字都在0~n-1的范围内. 如果这个数组中没有重复的数字,那么当数组排序之后数字i将出现在下标为i的位置.由于数组中有重复的数字,有些位置可能存在多个数字,同时有些位置可能没有数字.

现在让我们重排这个数组.从头到尾一次扫描这个数组中的每个数字。当扫描到下标为i的数字时,首先比较这个数字(用m表示) 是不是等于i. 如果是,则接着扫描下一个数字;如果不是,则再拿它和第m个数字进行比较.如果它和第m个数字相等,就找到了一个重复的数字(该数字在下标为i和m都出现了);如果它和第m个数字不相等,就把第i个数字和第m个数字交换,把m放到属于他的位置.接下来再重复这个比较,交换的过程,直到我们发现一个重复的数字.

以数组{2,3,1,0,2,5,3}为例来分析找到重复数字的步骤.数组的第0个数字是2 (如下图所示),与它的下标不相等

在这里插入图片描述

于是把它和下标为2的数字1交换 得到下图;
在这里插入图片描述
仍然与下标不等,继续和下标为1的数字交换 得到下图;
在这里插入图片描述
仍然与下标不等,继续和下标为3的数字交换 得到下图;这时由于0-3下标都相等 所以我们循环来的下标为4的元素,此时nums[4] == nums[nums[4]] 于是我们就找到了第一个重复的元素
在这里插入图片描述

如果要找第二个,第三个重复的元素,也是如此

好了 来编码

这个代码只是找出第一个相同元素,如果要找出所有,用数组返回就行了,思路一样

class Solution {
    public int findRepeatNumber(int[] nums) {
        if(nums.length <= 0){
            throw new RuntimeException("nums 长度小于0");
        }
        int m = -1;
        for(int i =0 ;i<nums.length;i++){
            while(nums[i] != i){
                if(nums[i] == nums[nums[i]]){
                   // System.out.println(nums[i]);
                   m=nums[i];
                   break;
                }
                int temp = nums[i];
                nums[i] = nums[temp];
                nums[temp] = temp;
            }
             if(m != -1){ //这个是如果找出了第一个 就停止遍历
                   // System.out.println(nums[i]);
                   break;
                }
        }
            return m;
    }
}

在这里插入图片描述
在这里插入图片描述
代码中尽管有两个循环,但是每个元素最多只用交换两次就能 找到属于它的位置,因此时间复杂度为O(n),操作都是在数组上的,所有空间复杂度为O(1);

发布了22 篇原创文章 · 获赞 28 · 访问量 2649

猜你喜欢

转载自blog.csdn.net/qq_43561507/article/details/104952073