在一个长度为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;
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图图是只猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值