时间限制: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;
}
注意:一定要考虑边界条件,即数组是否为空,数组的数字大小是否越界。
版权声明:本文为qq_31531635原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。