leetcode之数组中重复的数字

这篇博客讨论了如何解决LeetCode上的一个题目,即找出数组中重复的数字。提供了四种解法:使用HashSet记录出现次数、先排序后查找、使用临时数组以及交换位置查找。每种解法都有详细的解释和示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

题目

解法一:使用HashSet集合记录出现的次数

解法二:先排序后查找

解法三:使用临时数组

解法四:交换位置查找


题目

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

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

解法一:使用HashSet集合记录出现的次数

  • 使用集合存储已遍历的数据,新数据遍历时,判断是否在集合中存在重复的数据
//第一种解法
    public static int findRepeatNumber(int[] nums){
        //1.创建Set集合,将测试的数组存入集合中
      Set<Integer> set = new HashSet<>();
        for (int number : nums){
            //2.遍历传递进来的数组,将数组中的元素存入HashSet集合中
            //遍历数组快捷键  iter快捷键是一个增强for循环,查找每一个遍历出来的值
            if (set.contains(number)){
                System.out.println("发现重复元素"+number);
                return number;
                //3.使用HashSet集合中的Contains方法,
                //判断若第二次存入与之前有相同的元素就将这个元素返回
            }
            System.out.println("添加元素:"+number);
            set.add(number);
        }

        //若循环一遍数组中没有出现重复的数据,则返回-1
        return -1;//作为占位符,因为这个元素只会在0到n-1的范围内,-1就代表没有

    }

解法二:先排序后查找

  • 将数组排序后重复元素相邻
//解法二
    public static int findRepeatNumberOne(int[] nums){
        //Arrays类是java提供的操作数组的工具
        System.out.println(Arrays.toString(nums));
        Arrays.sort(nums);//sort方法是用来排序(从小到大排序)的
        System.out.println(Arrays.toString(nums));
        //itar快捷键普通的for循环
        //通过判断相邻元素是否相等,返回是否重复
        for (int i = 1; i < nums.length; i++) {
            if(nums[i]==nums[i-1]){
                return nums[i];
            }
        }
        return -1;
    }

解法三:使用临时数组

因为长度为 n 的数组 nums 里的所有数字都在 0~n-1的范围内,.

所以临时数组中的索引对应所有可能出现的数字 ,遍历时将出现数字对应到临时数组的索引位置更改元素值 0 改为 1

当临时数组的元素不为0时说明此索引位置已经出现过元素了

[2, 3, 1, 0, 2, 5, 3]

[0, 0, 0, 0, 0, 0, 0]

0 1 2 3 4 5 6

[0, 0, 1, 0, 0, 0, 0]

[0, 0, 1, 1, 0, 0, 0]

[0, 1, 1, 1, 0, 0, 0]

[1, 1, 1, 1, 0, 0, 0]

代码:注意:一定是先判断临时数组中的num索引位置的元素是否等于0,然后再赋值

public static int findRepeatNumberTwo(int[] nums){
        //{5, 3, 1, 0, 2, 5, 3}
        //先判断临时数组中的num索引位置的元素是否等于0,然后再赋值
        //定义一个临时数组,临时数组中的所有元素默认都是0
        int[] temp = new int[nums.length];
        System.out.println(Arrays.toString(nums));
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            //如果已经赋值代表nums中的元素重复出现
            if (temp[num] != 0 ){
        //若临时数组中对应的num索引的值temp[num]不等于0就证明当前的num值是重复的
                return num;
            }
            //找到临时数组的索引位置赋值为1
            temp[num]=1;
            System.out.println(Arrays.toString(temp));
        }
        return -1;
    }

解法四:交换位置查找

分析:

[2, 3, 1, 0, 2, 5, 3]

0 1 2 3 4 5 6

[0, 1, 2, 3, 2, 5, 3]

0 1 2 3 4 5 6

[2, 3, 1, 0, 2, 5, 3]

解题思路:

遍历数组的过程中,希望当前位置 和 出现元素正好匹配上。

先判断 ,是否匹配 , 如果不匹配 则进行交换 并且看当前索引位置的值是否与元素的值相同。

如果可以交换 ,交换之后 ,继续遍历当前位置 如果不可交换 即为重复元素 。

0 1 2 3 4 5 6

遍历2 交换2和1 [1,3,2,0,2, 5,3]

遍历1 交换1和3 [3,1,2,,0,2,5,3]

遍历3 交换3和0 [0,1,2,3,2,5,3]

遍历0 不交换

遍历1 不交换

遍历2 不交换

遍历3 不交换

遍历2 已经出现期望元素 是重复元素

public static int  findRepeatNumberTwo(int[] nums){
    System.out.println(Arrays.toString(nums));
        // [2, 3, 1, 0, 2, 5, 3]
        for (int i = 0; i < nums.length; i++) {
            // 如果索引正好等于元素本身  是期望的结果  则跳过此次循环,进入下一循环
            if (nums[i] == i) continue;
            // i = 0
            int num = nums[i]; // 2
           
            if (nums[num] == num) {
    // 如果当前索引位置的元素和当前索引是相等的话,说明有重复的数据,返回当前元素
                System.out.println("当前索引为" + num + "的位置 已经有" + num + "值,重复了");
                return num;
            }
            //交换位置,
            int tmp = nums[num]; // 1
            nums[num] = num;
            nums[i] = tmp;
            // [1, 3, 2, 0, 2, 5, 3]
            // 交换仍需遍历当前位置的值  所以抵消i++
            i--;
            System.out.println(Arrays.toString(nums));
        }

        return -1;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mate0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值