不修改数组找出重复的数字

不修改数组找出重复的数字

剑指offer

在一个长度为n+1的数组里面的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为9的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。

方法一

创建一个新n+1的数组data,遍历原来的数组如 2 将2存到 data[2]中, 3存到data[3]中…. 等下下次一遍历到3 发现data[3]=3 说明重复了。

`

public static void main(String[] args) {
    int [] array={2,3,5,4,3,2,6,7};
    //创建一个新的数组
    int [] newArray=new int[array.length];
    Map<Integer,Integer> map=new HashMap<>();
    for(int i=0;i<newArray.length;i++){
        //赋值为-1
        newArray[i]=-1;
    }

    for(int i=0;i<array.length;i++){
        if(newArray[array[i]]==array[i]){
            map.put(array[i],map.get(array[i])+1);
        }else{
            newArray[array[i]]=array[i];
            map.put(array[i],1);
        }
    }

    map.forEach((key,value)->{
        if (value>1){
            System.out.println(key +" : "+value);
        }
    });

`

结果:

分析:

统计个数是我自己加上去的

算法时间复杂度为 O(n),空间复杂度O(n)


方法二

使用二分法。 如:{2,3,5,4,3,2,6,7} 先二分,先统计在1~4里面的数字个数如果大于4则说明1~4里面有重复数字,否则5~7里面有重复数字。重复上面操作。

`

public static void main(String[] args) {
    int [] array={2,3,5,4,3,2,6,7};
    int length=array.length-1;
    int start=1,end=length;

    while(start<=end){
        //取中
        int middle=((end-start)>>1)+start;
        int count= getCount(array,start,middle);
        if(start==end){
            if(count>1){
                //输出重复数字
                System.out.println(start);
                break;
            }else {
                break;
            }
        }
        if(count>(middle-start+1)){
            end=middle;
        }else{
            start=middle+1;
        }
    }


}
//查找数组中值位于start和end之间的元素个数
public static int getCount(int[] array,int start,int end){
    if (array==null)
        return 0;
    int count=0;
    for(int i=0;i<array.length;i++){
        if(array[i]>=start&&array[i]<=end){
            count++;
        }
    }
    return count;
}

`

结果:

分析:二分查找logn ,但是getCount每个数组遍历一变 n,时间复杂度为O(nlogn),空间复杂度为O(1)。但是这个方法有个问题不能找出所有的重复元素

如{2,2,4,4,5,5} 找到的元素会是4。

start=1,end=5,middle=3。 1~3中元素有2个则4~5有重复

start=4,end=5,middle=4。 4有2个元素

start=4,end=4,middle=4, 返回4。

猜你喜欢

转载自blog.csdn.net/u013164931/article/details/79757777