剑指offer第二版 刷题打卡 day01 03.数组中重复的数字

题目:

03.找出数组中重复的数字。

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

示例 1:

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

思路:

这题我用了三种思路:

  • 使用哈希表。要查找数组中的重复值,可以使用哈希表记录该数组中的值,当查找到重复值时直接返回即可。

  • 原地交换。题目中给出关键信息,在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。也就是说数组下标数组元素一对多的关系。

可以将下标与值一一对应,直到遇到重复值。

  • 排序比较。使用Array工具类中的sort()方法使数组排序,接着nums[i]和nums[i+1]进行比较,若相等则直接返回nums[i]。

具体流程:

方法一:哈希表

1.创建哈希表dic

2.依次判断数组中的元素是否在哈希表中有相同元素。

3.若有则直接返回;若没有则将该元素记录到哈希表中。

4.重复2,3步直到数组遍历完全,若遍历完尚未返回,返回-1。

class Solution {
    public int findRepeatNumber(int[] nums) {
       Set<Integer> dic=new HashSet<>();
       for(int i=0;i<nums.length;i++){//这里for循环可改为for(int num:nums)num等同于nums[i]
            if(dic.contains(nums[i])) return nums[i];
              dic.add(nums[i]);
          
       }
        return -1;
    }
}

执行结果:

方法二:原地交换

1.循环判断索引i与对应元素nums[i]是否相等,

2.相等则i+1;不相等则判断nums[i]与nums[nums[i]]是否相等,

若相等则直接返回nums[i];若不相等则将两值替换位置。

3.循环第二步判断,直到索引i与对应元素nums[i]相等。

4.若遍历完尚未返回,则返回-1。

注意:方法二的解法有一个关键点是只有 nums[i] == i 的时候i才递增,这样保证找到相同元素前不会漏掉某些元素的处理。否则很容易变成以下做法。

错误做法:

class Solution {
      public static int findRepeatNumber(int[] nums) {  //原地交换
        int x=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==i)
                continue;
            else if(nums[nums[i]]!=nums[i]) {
                x = nums[nums[i]];
                nums[nums[i]] = nums[i];
                nums[i] = x;
            }
            else return nums[i];
        }
        return -1;
    }
}

正确做法:

class Solution {
      public static int findRepeatNumber(int[] nums) {  //原地交换
         int x=0;
        for(int i=0;i<nums.length;i++){
          while(nums[i]!=i)   //关键点,没有这步可能会遗漏元素。
            {
                if (nums[nums[i]] != nums[i]) {
                    x = nums[nums[i]];
                    nums[nums[i]] = nums[i];
                    nums[i] = x;
                } else return nums[i];
            }
        }
​
        return -1;
      }     
}

执行结果:

方法三:排序比较

1.使用Array类中的sort()方法对数组进行排序。

2.将数组中的元素nums[i]和nums[i+1]进行比较。

若相同则直接返回nums[i]。

3.若遍历完尚未返回,则返回-1。

class Solution {
      public static int findRepeatNumber(int[] nums) {  //排序两两比较法 
          Arrays.sort(nums);
        for (int i = 0; i <nums.length-1 ; i++) {
          if( nums[i]==nums[i+1])
          return nums[i];
        }
      return -1;
      }     
}

执行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值