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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_31531635/article/details/79796419

时间限制:1秒空间限制:32768K

题目描述

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

原始解法–利用计数排序思想

运行时间:4ms
占用内存:512k

bool duplicate(int numbers[], int length, int* duplication) {
    int *A = new int[length];
    for(int i=0;i<length;i++) A[i]=0;
    for(int i=0;i<length;i++)
    {
        A[numbers[i]]++;
    }
    int num=0;
    while(A[num]<2 && num != length)
    {
        num++;
    }
    delete [] A;
    if(num == length) return false;
    else
    {
        *duplication = num;
        return true;
        break;
    }
    return true;
}
优化解法一–直接在叠加循环中找到第一个重复的数,减少冗余–未修改数组

运行时间:3ms
占用内存:356k

    bool duplicate(int numbers[], int length, int* duplication) {
        int *A = new int[length];
        int num=0;
        for(int i=0;i<length;i++) A[i]=0;
        for(int i=0;i<length;i++)
        {
            A[numbers[i]]++;
            if(A[numbers[i]]>=2 && num==0)
            {
                *duplication=numbers[i];
                num++;
                return true;
                break;
            }
        }
       if(num ==0)return false;
        return true;
    }
优化解法二–修改了数组
基本思想

      由于题目中,n个数的数组中的整数范围为0~n-1,因此,当没有重复的数字时,对数组排序,必然有i大小的整数对应数组的第i个位置,但如果有重复的数字,有些位置可能没有数字,有些可能有多个数字。
      现在来重排这个数组,即从头到尾依次扫描这个数组中的每个数字。当扫描到下标为i的整数时,首先比较这个数字(用m表示)是不是等于i。如果是,则继续扫描下一个数字;如果不是,则再拿它和第m个数字进行比较。如果它和第m个数字相等,就找到了一个重复的数字(该数字在下标为i和m的位置都出现了);如果它和第m个数字不相等,就把第i个数字和第m个数字进行交换,把m放到属于它的位置。接下来再重复这个比较、交换的过程,知道发现一个重复的数字。
运行时间:3ms
占用内存:376k

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;
                break;
            }
            int temp=numbers[i];
            numbers[i]=numbers[temp];
            numbers[temp]=temp;
        }
    }
    return false;
}

注意:一定要考虑边界条件,即数组是否为空,数组的数字大小是否越界。

猜你喜欢

转载自blog.csdn.net/qq_31531635/article/details/79796419