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

剑指Offer

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

提示

  1. 排序思想
  2. 哈希表
  3. 题目数组特性

解题思路

排序思想(简单)
利用数组排序算法
排序后很容易找到

哈希表思想
模拟一个哈希表的思想
对数组进行一个哈希表的插入操作
这里由于都是小于n的数字
可以采用对n取余的操作进行哈希
哈希冲突值就是重复的值
空间负责度O(n)
时间复杂度O(n)

数组 0 到n-1特性(牛逼)
题目数组:0到n-1
数组下标:0到n-1
数组值 0到n-1对应 数组 的 下标 0到n-1 进行放置!!!
就是将数组的值依次按下标放置,一旦放置的下标存在一样的值就是找到.

实例:{3,1,4,2,1}

  1. 判断3是否处于正确的位置
  2. 如果不处于正确的位置将3交换到3的位置:{2,1,4,3,1}
  3. 继续交换 {4,1,2,3,1},{1,1,2,3,4}
  4. {1,1,2,3,4}这个时候再执行1的交换的时候发现1已经存在了
  5. 所以返回1

时间复杂度O(n) 这个我还在想怎么算的?
空间复杂度O(1)

代码实现

排序思想

public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null || duplication == null) {
            return false;
        }
        if(numbers.length == 0 || duplication.length == 0){
            return false;
        }
        if(numbers.length != length){
            return false;
        }
       //选择排序的思想
        for(int i = 0;i < length-1; i++){
            for(int j = i+1; j < length; j++) {
                if(numbers[j] > length -1){
                    return false;
                }
                
                if(numbers[i] == numbers[j]) {
                    duplication[0] = numbers[i];
                    return true;
                }
            }
        }
        return false;
}

哈希表思想

public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null || duplication == null) {
            return false;
        }
        if(numbers.length == 0 || duplication.length == 0){
            return false;
        }
        if(numbers.length != length){
            return false;
        }
       //空间换时间
        int[]  hash = new int[length];
        for(int i = 0; i < length; i++){  
            if(numbers[i] >= length){
               return false;
            }
            int key = numbers[i]%length;
            if(hash[key] != 0 ){
                duplication[0] = hash[key]; 
                return true; 
            }
            hash[key] = numbers[i];
        }  
        return false;
}

数组 0 到n-1特性(牛逼)

public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null || duplication == null) {
            return false;
        }
        if(numbers.length == 0 || duplication.length == 0){
            return false;
        }
        if(numbers.length != length){
            return false;
        }
        for(int i = 0; i < length; i++){    
            if(numbers[i] >= length){
               return false;
            }  
            //不处于正确的位置上
            while(numbers[i] != i){
                //正确的位置上已经有值了
                if(numbers[i] == numbers[numbers[i]]){
                    duplication[0] = numbers[i];
                    return true;
                }
                int swap = numbers[i];
                numbers[i] = numbers[swap];
                numbers[swap] = swap; 
            }      
        }   
        return false;
    }

你可能感兴趣的:(算法之美)