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

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

传送门

题目

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

限制:

2 <= n <= 100000

方法一:用HashSet

复杂度分析

  • 时间复杂度 O(N) : 遍历数组使用 O(N) ,HashSet 添加与查找元素皆为 O(1) 。
  • 空间复杂度 O(N) : HashSet 占用 O(N) 大小的额外空间。

Code:

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

方法二:原地交换

思路:

​ 题目说一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内,那么数组元素的索引应该是一对多的关系,因此,可遍历数组并通过交换操作,使元素的 索引 对应(即 nums[i]=i )

​ 在遍历中,第一次遇到数字x时,将其交换到索引处x;而当第二次遇到数字x时,一定已经有nums[x]=x,此时的这个x就是多出来的
通俗易懂的解释:

​ 这个原地交换法就相当于分配工作,每个索引代表一个工作岗位,每个岗位必须专业对口,既0索引必须0元素才能上岗。而我们的目的就是找出溢出的人才,既0索引岗位有多个0元素竞争。

​ 我们先从0索引岗位开始遍历,首先我们看0索引是不是已经专业对口了,如果已经专业对口既nums[0]=0,那我们就跳过0岗位看1岗位。如果0索引没有专业对口,那么我们看现在0索引上的人才调整到他对应的岗位上,比如num[0]=2,那我们就把2这个元素挪到他对应的岗位上既num[2],这个时候有两种情况:1、num[2]岗位上已经有专业对口的人才了,既num[2]=2,这就说明刚刚那个在num[0]上的2是溢出的人才,我们直接将其返回即可。2、num[2]上的不是专业对口的人才,那我们将num[0]上的元素和num[2]上的元素交换,这样num[2]就找到专业对口的人才了。之后重复这个过程直到帮num[0]找到专业对口的人才,然后以此类推帮num[1]找人才、帮num[2]找人才,直到找到溢出的人才。

算法流程:

  1. 遍历数组nums,设初始索引值为i=0;
    • nums[i]=i 说明此数字已在对应索引位置,无需交换,因此跳过 ;
    • nums[nums[i]]=nums[i]:代表索引nums[i]处和索引i处的元素都为nums[i],找到一组重复值,返回该值nums[i]
    • 否则:交换索引为inums[i]的元素值,将此数字交换至对应索引位置。
  2. 若遍历完毕尚未返回,则返回-1。

复杂度分析

  • 时间复杂度 O(N) : 遍历数组使用 O(N) ,每轮的判断和交换操作使用O(1)。
  • 空间复杂度 O(1) : 使用常熟复杂度的额外空间。

Code:

class Solution {
    public int findRepeatNumber(int[] nums) {
        int len = nums.length;
        int i = 0;
        while (i < len) {
            if (nums[i] == i) {
                i++;
                continue;
            }
            if (nums[nums[i]] == nums[i]) return nums[i];
            int temp = nums[i];
            nums[i] = nums[temp];
            nums[temp] = temp;
        }
        return -1;
    }
}
posted @   QING~h  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航