剑指offer——数组中重复的数字

写完了二维数组中的查找之后,据相同知识点,找到了这个题,原题目地址:数组中重复的数字

为方便直接看,先抄写一下题目:

题目描述:

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

题目分析:

首先可以判断出来数组是一维的。然后需要找到任意一个重复的元素,将其输出。

但是题目中并没有说数组是有序的

第1个方法:为数组排个序,然后比较相邻的两个元素是否相等。

第2个方法:另外创建一个数组,从该数组中取出元素放入新数组;放入之前先比较新数组中是否有该元素,若有,则该数重复。

对于方法1,涉及到数组的排序,复杂度比较高,所以不太合适;对于方法2,则相对减少了比较的次数,但是多开辟了空间。该方法的实现代码如下:

public boolean duplicate(int numbers[],int length,int [] duplication) {
        //开辟一个空间存储各类别的数字方法
        if(numbers == null || length <= 0){
            return false;
        }
        int[] element = new int[length];
        element[0] = -1;
        int ele = 1;
        for(int i=0; i<length; i++){
            for(int j=0; j<ele; j++){
                if(numbers[i] == element[j]){
                    duplication[0] = numbers[i];
                    return true;
                }
            }
            element[ele-1] = numbers[i];
            ele++;
        }
        return false;
    }
View Code

这种方法有点小问题:由于创建int型数组时会自动赋初值为0;所以当出现0元素时,该方法将无法正确判断。要保证正确,则需要使初始化数组不为0,经过查找,发现对于int型的数组,要初始化为指定数值,则需要遍历每个元素进行赋值。所以此方法又额外增加了很大的负担。

再仔细阅读题目,可以发现:数组的长度为n,数字在0到n-1的范围,说明当且仅当数组中的元素恰好为0到n-1这n个数时,数组是不重复的;其他情况都有重复的数字。

利用数组本身的特性,我们不妨将数组进行这样的排序:

将每个元素放到与下标一致的位置,若存放某个元素时,发现该下标位置已经存在一个相同的元素,说明该元素重复。这样操作可以一边排序一边查找。实现代码如下:

public boolean duplicate(int numbers[],int length,int [] duplication) {
        //交换元素到对应下标位置
        if(length <= 0 || numbers == null){
            return false;
        }
        //用于交换的中间变量
        int swap = -1;
        //数组下标起始位
        int tag = 0;
        while(tag < length){
            //数组对应下标的元素
            int num = numbers[tag];
            //若元素值等于下标值,则下标自加
            if(num == tag){
                tag++;
            }else{    //否则以元素值作为下标值,判断该下标值处的元素是否和下标值相等
                if(numbers[num] == num){    //若已相等,说明该元素值重复
                    duplication[0] = num;
                    return true;
                }else{    //若不相等,则交换两个元素,使后者位置元素与下标相等
                    swap = num;
                    numbers[tag] = numbers[num];
                    numbers[num] = swap;
                }
            }
        }
        return false;
    }
View Code

 此代码在牛客网上运行时间为27ms。

原文地址:https://www.cnblogs.com/shengguilv/p/12779818.html