题目简介:
和之前那个题目差不多,但之前那个是用的修改数组的方法,此题目限制不能修改数组,所以我们需要寻找更好的方法。
题目分析:
其实就是给定一个数组,数组中包含重复元素,我们需要想一些方法来解决如何找到这些重复元素
解题思路:
在没有翻阅书籍前,暂时只能想出创建哈希表的方式,通过遍历哈希表来找到重复数字。书中介绍的类似二分查找,简单而言就是多次统计数字出现次数。在一个长度为n+1的数组中存在0-n的数字一定会存在一个或者多个重复数字,所以我们就可以利用这个特点,我们可以先找到0-n的中间值,通过中间值来把这个数字组分成两个部分,(0,n/2】和(n/2+1,n】,如果某一个范围内存在的的数字个数超过其最大值,则一定存在重复数字,一轮轮统计就一定能找到重复数字。也就是说例如数组:{2,3,5,4,3,2,6,7},先把这个数组分成1-4和5-7两个范围,统计这两个范围内的数字有几个,1-4有五个数字,所以一定存在重复数字,5-7只有三个所以下一阶段就是再把1-4分为1-2和3-4,就这样就可以一步步统计出重复的数字是哪个。
代码实现:
int countRange(const int *nums, int length, int start, int end)
{
if(nums == NULL)
return 0;
int count = 0;
for(int i=0; i<length; i++)
{
if(nums[i]>=start && nums[i]<=end)
++count;
}
return count;
}
int getDuplication(const int *nums, int length)
{
if(nums == NULL || length <= 0)
return -1;
int start = 1;
int end = length - 1;
while(start <= end)
{
int mid = (start+end)/2;
int count = countRange(nums, length, start, mid);
if(start == end)
{
if(count > 1)
return start;
else
break;
}
if(count > (mid - end + 1))
end = mid;
else
start = mid + 1;
}
return -1;
}