剑指offer算法题(二)数组中重复的数字

剑指offer算法题2

数组中重复的数字

题目描述

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


解题思路1:

由于所有数字都在 0~n-1 之间,因此,当一个数字被访问过后,可以设置对应位上的数 + n,之后再遇到相同的数时,会发现对应位上的数已经大于等于n了,那么直接返回这个数即可。

代码实现:

class Solution {
public:
    bool duplicate(int numbers[], int length, int* duplication) {      
        for(int i=0;i<length;i++){            
            int j=numbers[i]%length;
            numbers[j]+=length;
            if(numbers[j]>=(2*length)){
                *duplication = numbers[j]%length; 
                return true;
            }                                  
        }
        return false;       
    }
};

优点:算法复杂度低:时间算法复杂度 O(n) O ( n ) ,不需要额外空间。
缺点:可能出现溢出情况,对原数组进行了修改。


解题思路2:

使用长度为n的记录数组 ,初始值设为0, 遍历原数组,每个数字都在记录的数组上+1,若记录数组上的该数字已经等于1,返回该数。

代码实现:

class Solution {
public:
    bool duplicate(int numbers[], int length, int* duplication) {
        int temp[length];
        memset(temp, 0, sizeof(temp)); 
        // 局部数组没有默认值,如果声明的时候不定义,则会出现随机数。
        for(int i=0;i<length;i++){
            temp[numbers[i]]++;
            if(temp[numbers[i]] >1){
                *duplication = numbers[i];
                return true;
            }
        }
        return false;
    }
};

优点:时间算法复杂度 O(n) O ( n ) ,不改变原数组。
缺点:空间复杂度高,需要 O(n) O ( n )


解题思路3

从头到位扫描数组,当扫描到下标为i的数字m时,如果是,则扫描下一个数字;如果不是,则那它和第m个数字比较:如果相等,就返回这个重复的数字,如果不相等,就把第i个数字和第m个数字交换。

例子:
{2,3,1,0,2,5,3}
第0个和第2个比较,交换
{1,3,2,0,2,5,3}
第0个和第1个比较,交换
{3,1,2,0,2,5,3}
第0个和第3个比较,交换
{0,1,2,3,2,5,3}
第0个是0,第1个是1,第2个是2,第3个是3
第4个是2,第2个也是2,找到重复数字,返回

代码实现:

class Solution {
public:
    bool duplicate(int numbers[], int length, int* duplication) { 
        if(numbers == nullptr || length <= 0)
            return false;
        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 = numbers[i];
                    return true;
                }
                int tmp = numbers[i];
                numbers[i] = numbers[tmp];
                numbers[tmp] = tmp;
            }                                  
        }
        return false;       
    }
};

优点:算法复杂度低:时间算法复杂度 O(n) O ( n ) ,不需要额外空间;不会出现溢出情况。
缺点:对原数组进行了修改。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值