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

题目描述:在一个长度为n的数组里的所有数字都在0~n-1的范围内,数组中一些数字是重复的,但不知道有几个数字重复,也不知道每个数字重复了几次,请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3.
思路:从下标为0的数开始,将数值与下标值比较。若不等,就将此数与下标等于此数的那个数值交换,直到此数与下标相等,再扫描下一个数,重复之前的比较步骤。
注意:此方法修改原数组的方法

package Function;
//o(n) o(1)
public class duplicate03 {
    public  boolean duplicate( int numbers[],int length, int[]duplication){
        //输入空指针,或者数组长度小于0
        if(numbers ==null||length<=0){
            return false;
        }
       //防止长度为n的数组中包含0-n-1之外的数字
        for (int i =0;i<length;++i){
            if(numbers[i]<0 ||numbers[i]>length-1)
                return false;
        }
        for (int i = 0; i<length;++i){
            //索引不等于值
            while(numbers[i]!=i){
                if(numbers[i]==numbers[numbers[i]]){
                    duplication[0]=numbers[i];
                    return true;
                }
                int temp =numbers[i];
                numbers[i]=numbers[temp];
                numbers[temp]=temp;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        int [] arr1={};
        int [] arr2 = new int[7];
        duplicate03 p =new duplicate03();
        boolean i =p.duplicate(arr1,0,arr2);
        System.out.println(i);
        //int [] arr1={};
        //boolean i =p.duplicate(arr1,0,arr2);
    }
}

若不修改原数组,找到数组中重复的数字代码如下:

package Function;
//不修改数组意味着不交换
//另一个方法就是新创建一个数组,将数值复制到相应的索引值去
//0(nlogn) 0(1)以时间换空间
//二分查找
public class NoalterDuplicate03 {
    public int NoalterDuplication(int numbers[],int length){
        if(numbers==null||numbers.length<=0){
            return -1;
        }
        for(int i =0;i<length;++i){
            if(numbers[i]<0||numbers[i]>length-1)
                return -1;
        }
        //索引值 加减索引0参与无意义
        int start = 1;
        int end =length-1;
        //开始标志
        while(end>=start){
           int middle=((end-start)>>1)+start;
           int count=countRange(numbers,length,start,middle);
           //一分为二,统计一个数的时候,此数出现多次
           if(end==start){
               if(count>1)
                   return start;
               else
                   break;
           }
           if(count>(middle-start+1))
               end=middle;//左边有重复
           else
               start=middle+1;//右边有重复
        }
        return -1;
    }
    public int countRange(int numbers[], int length,int start, int end){
        int count=0;
        for(int i =0;i<length;++i){
            //计算数组中所有出现在区间的个数
            if(numbers[i]>=start&&numbers[i]<=end){
                ++count;
            }
        }
        return count;
    }
    public static void main(String[] args) {
       int[]arr1 ={3,2,2,4,8,8,4,5,6};
       NoalterDuplicate03 p=new NoalterDuplicate03();
       int i=p.NoalterDuplication(arr1,9);
       System.out.println(i);
    }
}
发布了9 篇原创文章 · 获赞 0 · 访问量 469

猜你喜欢

转载自blog.csdn.net/qq_36113761/article/details/104599448