题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
参考<<剑指Offer>>一书。
1、当该数组是无序时,遍历该数组,将该数组的每一个元素和它后面的元素作比较,若相同则函数返回。该方法的时间复杂度为O(n^2)。
bool complicatefindduplicate(int *arr,int len,int *duplicate)
{
if(arr==NULL||len<=0)
return false;
for(int ii=0;ii<len;ii++)
for(int jj=ii+1;jj<len;jj++)
{
if(arr[ii]==arr[jj])
{
*duplicate=arr[ii];
return true;
}
}
return false;
}
2、当数组是无序时,可以先利用快速排序法对数组进行排序,然后再分别比较相邻元素是否相同,若相同则函数返回。
//快速排序 分治法
void sortcore(int * arr,int l,int r)
{
if(l>=r)//递归结束的条件
return;
int val=arr[l];//中间值
int left=l;
int right=r;
while(left<right)
{
while(left<right&&arr[right]>=val)
right--;
if(left<right)
arr[left++]=arr[right];
while(left<right&&arr[left]<=val)
left++;
if(left<right)
arr[right--]=arr[left];
}
arr[left]=val;
sortcore(arr,l,left-1);//递归
sortcore(arr,left+1,r);//递归
}
void sort(int *arr,int len)
{
if(arr==NULL||len<=0)//判断条件
return;
sortcore(arr,0,len-1);
}
bool findduplicate(int *arr,int len,int *duplicate)
{
if(arr==NULL||len<=0)
return false;
sort(arr,len);
for(int ii=0;ii<len-1;ii++)
{
if(arr[ii]==arr[ii+1])
{
*duplicate=arr[ii];
return true;
}
}
return false;
}
3、利用哈希表解决这个问题。从头到尾按顺序扫描数组的每个数,每扫描到一个数字的时候,都可以用O(1)的时间来判断哈希表里是否已经包含了该数字。
如果哈希表里还没有这个数字,就把它加入哈希表中;如果哈希表里已经存在该数字,那么就找到一个重复的数字。这种方法时间复杂度为O(n),空间复杂度为O(n)。
bool hashfindduplicate(int *arr,int len,int *duplicate)
{
if(arr==NULL||len<=0)
return false;
int max=arr[0];
for(int ii=1;ii<len;ii++)
if(max<arr[ii])
max=arr[ii];
int * hash=new int[max+1];
memset(hash,0,(max+1)*sizeof(int));
for(int ii=0;ii<len;ii++)
{
if(hash[arr[ii]]==0)
{
hash[arr[ii]]++;
}
else
{
*duplicate=arr[ii];
return true;
}
}
delete hash;
return false;
}
测试程序
#include<iostream>
using namespace std;
void sort(int *arr,int len);
void mergesort(int *arr,int len);
bool findduplicate(int *arr,int len,int *duplicate);
bool hashfindduplicate(int *arr,int len,int *duplicate);
bool complicatefindduplicate(int *arr,int len,int *duplicate);
void test1()
{
int numbers[] = {2, 1, 3, 0, 4};
int duplicate=0;
if( findduplicate(numbers,sizeof(numbers)/sizeof(int),&duplicate) )
cout<<duplicate<<endl;
else
cout<<"No duplicate"<<endl;
if( hashfindduplicate(numbers,sizeof(numbers)/sizeof(int),&duplicate) )
cout<<duplicate<<endl;
else
cout<<"No duplicate"<<endl;
if( complicatefindduplicate(numbers,sizeof(numbers)/sizeof(int),&duplicate) )
cout<<duplicate<<endl;
else
cout<<"No duplicate"<<endl;
}
void test2()
{
int numbers[] = {2, 1, 3, 3, 4};
int duplicate=0;
if( findduplicate(numbers,sizeof(numbers)/sizeof(int),&duplicate) )
cout<<duplicate<<endl;
else
cout<<"No duplicate"<<endl;
if( hashfindduplicate(numbers,sizeof(numbers)/sizeof(int),&duplicate) )
cout<<duplicate<<endl;
else
cout<<"No duplicate"<<endl;
if( complicatefindduplicate(numbers,sizeof(numbers)/sizeof(int),&duplicate) )
cout<<duplicate<<endl;
else
cout<<"No duplicate"<<endl;
}
int main()
{
test1();
test2();
return 0;
}
测试结果: