1、在一个长度为n的数组里的所有数字都在0~n-1的范围内,数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数字中任意一个重复的数字。例如,如果输入长度为7的数字{2, 3, 1, 0, 2, 5, 3},那么对应的输出是重复的数字2或者3.
程序:
bool duplicate(int numbers[],int length,int *duplication)
{ int temp;
if(numbers==NULL||length<=0)
{
return false;
}
for(i=0;i<length;i++)
{
if(numbers[i]<0||numbers[i]>length-1)
return false;
}
for(i=0;i<length;i++)
{
if(numbers[i]!=i)
{
if(numbers[i]==numbers[numbers[i]])
{ *dublication=numbers[i];
return ture;
}
temp=numbers[numbers[i]];
numbers[numbers[i]]=numbers[i];
numbers[i]=temp;
}
}
return false;
}
时间复杂度O(n),空间复杂度O(1)。
2、不修改数组找出重复的数字(与题目一一样,只是找出任意一个重复的数字即可,,没有要求找出所有的重复数字)
在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改输入的数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3
时间复杂度O(nlogn),空间复杂度是O(1)
思路解析:为什么会有重复的数字,假如没有重复的数字,那么在1~n的范围里有n个数字,如果有n+1个数字则说明至少有一个数字是重复的。可以把1~n的数字从中间的数字m分为两部分,前面一半为1~m,后面一半为m+1~n,如果1~m的数字的个数超过m个则说明里面有重复的数字,否则另一半的数组里一定有重复的数字,。然后继续把包含重复数字的数组区间一分为二,直到找到一个重复的数字
程序:
int GetDuplication(const int*numbers,int length)
{
if (numbers==NULL||lenth<=0)
return -1;
int start=1;
int end=length-1;
while(end>=start)
{
int middle=start+((end-start)>>1);
int count=countRange(numbers,length,start,middle);
if(end==start)
{
if(count>1)
return start;
else
break;
}
if(count>(middle-start+1))
end=middle;
else
start=middle+1;
}
return -1;
}
int CountRange(const int*numbers,int length,int start,int end)
{
if(numbers==NULL)
return 0;
int count=0;
for(int i=0;i<length;i++)
if(numbers[i]>=start&&numbers[i]<=end)
++count;
return count;
}