zoukankan      html  css  js  c++  java
  • 剑指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。

  • 相关阅读:
    tcpdump分析tcp连接的建立、传输和关闭
    链表排序:冒泡和快排
    linux文件IO操作篇 (一) 非缓冲文件
    linux文件操作篇 (四) 目录操作
    linux文件操作篇 (三) 文件状态和操作属性
    linux文件操作篇 (二) 打开和关闭文件
    linux文件操作篇 (一)文件属性与权限
    linux编程(三)多线程
    linux编程(二)进程
    linux编程(一)文件IO 目录
  • 原文地址:https://www.cnblogs.com/shengguilv/p/12779818.html
Copyright © 2011-2022 走看看