题目:
在一个长度为n+1的数组里的所有数字都在1到n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2或3。
思路:
方法1:利用辅助空间,时间复杂度O(n),空间复杂度O(n)
方法2:二分法,时间复杂度O(nlogn),空间复杂度O(1)
将1~n的数组从中间位置m分为两半,前面一半1~m,后面一半m+1~n,统计数组中在1~m范围内的数字个数,如果超过m,说明这一区间一定包含重复的数字,否则另一区间一定包含重复的数字。继续一分为二的操作,直到找到重复的数字。
代码:
VC下测试通过:
#include <iostream>
#include <algorithm>
using namespace std;
int countRange(const int* numbers, int length, int start, int end)
{
if(numbers==NULL || length<=0)
return 0;
int count=0;
for(int i=0;i<length;i++)
{
if(numbers[i]<=end && numbers[i]>=start)
count++;
}
return count;
}
int getDuplicate(const int* numbers, int length)
{
if(numbers==NULL || length<=0)
return -1;
int left=0;
int right=length-1;
int mid;
while(left<=right)
{
mid=left+((right-left)>>1);
int count=countRange(numbers, length, left, mid);
if(left==right)
{
if(count>1)
return mid;
else
return -1;
}
if(count>mid-left+1)
right=mid;
else
left=mid+1;
}
return -1;
}
int main()
{
int numbers[7]={2,3,1,0,2,5,3};
int length=7;
cout<<getDuplicate(numbers, length)<<endl;
return 0;
}