在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,请找出数组中任意一个重复的数字。
例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是一个重复的数字2。
基本思路:由于数组内元素的值限定在 【0,N) 区间内,采用快速Hash的方式 O(N)时间复杂度 快速定位并及时退出
bool duplicate(int numbers[], int length, int* duplication) {
bool* visit=new bool[length];//访问数组
for(int i=0;i<length;i++)
visit[i]=false;
for(int i=0;i<length;i++)
{
int value=numbers[i];
if(visit[value]==true) //之前访问过
{
*duplication=value;
return true;
}
//一般情况 在对应位置标记为已访问
visit[value]=true;
}
//循环结束 还没有找到
*duplication=-1;
return false;
}
进阶思路:在不开辟新的空间情况下 ,由于数组元素大小不超过 N ,在原先数组基础上对应角标处+=N
每次遇到一个元素,由于需要通过value角标定位 先判断是否大于N 是的话value-=N;
来定位到value的存放位置,若那个位置的值大于N 说明之前被赋值过 也就遇到重复现象 返回
若那个位置小于N(说明没有被+=N) 则在numbers[value]处+=N
bool duplicate(int numbers[], int length, int* duplication) {
for(int i=0;i<length;i++)
{
int value=numbers[i];//该数组位置的值
if(value>=length)
value-=length;
if(numbers[value]>length) //说明之前在对应位置+N 也就是遇到重复了
{
*duplication=value;
return true;
}
//一般情况 是在value下标处的位置上+N
numbers[value]+=length;
}
//循环结束还没有找到 返回false
*duplication=-1;
return false;
}