剑指Offer-03-数组中重复的数字-详解+代码实现

剑指Offer 03题

找出数组中重复的数字

  • 题目描述:

    在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

  • 思路一:临时数组

    • 申请一个临时数组,长度为num.length;
    • 遍历数组nums;如果nums[i]是几,就给临时数组第几个位置加1;
    • 判断临时数组的元素,如果大于1,则出现重复值。
      借助临时数组判断
  • 思路二:先排序再查找

    • ①利用Arrays.sort()方法对数组进行排序;
    • ②如果有重复的值,排序之后一定是相邻的数,比较相邻两个数是否相等即可。
    • ③注意:从1位置开始遍历,每次比较该位置与前一个位置的数是否相等;因为如果从0位置开始遍历,只能与后一个位置的数比较,这样到第nums.length-1位置比较时,会越界。
  • 思路三:放在指定位置

    • ① 对数组归位,遍历该数组;
    • ②判断nums[i]是不是i(即判断第i个位置的数是不是i),如果不是,比较它和第num[i]个位置上的数,即判断nums[i]和nums[nums[i]];
    • ③若nums[i]和nums[nums[i]]相等,则找到重复的值,返回nums[i];若不相等,则交换(第i位置的数与第num[i]位置上的数);
    • ④再重复这个比较,直到找到重复的值。
  • 代码实现:

import java.util.Arrays;
public class Test03 {
    public static void main(String[] args) {
        Test03 test03 = new Test03();
        int[] a = {2, 3, 1, 0, 2, 5, 3};
        //System.out.println(test03.findRepeatNumber1(a));
        //System.out.println(test03.findRepeatNumber2(a));
        System.out.println(test03.findRepeatNumber3(a));
    }

    //1.临时数组
    public int findRepeatNumber1(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.先排序再查找
    public int findRepeatNumber2(int[] nums) {
        Arrays.sort(nums);
        //从1位置开始遍历,每次比较该位置与前一个位置的数是否相等
        for (int i = 1; i < nums.length; i++) {   
            if (nums[i] == nums[i - 1]) {
                return nums[i];
            }
        }
        return -1;
    }

    //3.放在指定位置
    public int findRepeatNumber3(int[] nums){
        for(int i = 0; i < nums.length; i++){
            if(nums[i] != i){
                if(nums[nums[i]] == nums[i]){
                    return nums[i];
                }else{
                    int temp = nums[i];
                    nums[i] = nums[temp];
                    nums[temp] = temp;
                }
            }
        }
        return -1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值