要求:不修改数组找出重复的数字
在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少存在一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。
测试用例:
- 长度为n的包含一个或多个重复的数字
- 不包含重复的数字
- 无效输入测试用例(输入空指针)
本题考点:
- 考查对一维数组的理解和编程能力。一维数组在内存中占据连续的空间,因此我们可以根据下标定位对应的元素。
- 考查对二分查找算法的理解,并能快速、正确地实现二分查找算法的代码。
- 考查沟通能力,只有具备良好的沟通能力,才能充分了解面试官的需求,从而有针对性地选择算法解决问题。
源代码:
/********************************************************************
* 参数:
* numbers: 一个整数数组
* length: 数组长度
* min: 最小值
* max: 最大值
* 返回值:
* 正数: 输入有效,出现在范围内的次数
* 负数或0: 输入无效
********************************************************************/
int countRange(const int *numbers, int length, int min, int max)
{
if (nullptr == numbers)
return 0;
int count = 0;
for (int i = 0; i < length; i++)
{
if (numbers[i] >= min && numbers[i] <= max)
++count;
}
return count;
}
/********************************************************************
* 参数:
* numbers: 一个整数数组
* length: 数组长度
* 返回值:
* 正数: 输入有效,并且数组中存在重复的数字,返回值为重复值
* 负数: 输入无效,或者数组中没有重复的数字
********************************************************************/
int getDuplication(const int *numbers, int length)
{
//无效输入(空指针)
if (nullptr == numbers || length <= 0)
return -1;
//不包含重复的数字
int min = 1;
int max = length - 1;
for (int i = 0; i < length; ++i)
{
if (numbers[i] < min || numbers[i] > max)
return -1;
}
//有效输入
while (max >= min)
{
int middle = ((max - min) >> 1) + min;
int count = countRange(numbers, length, min, middle);
if (max == min)
{
if (count > 1)
return min;
else
break;
}
if (count > (middle - min + 1))
max = middle;
else
min = middle + 1;
}
return -1;
}
参考代码:https://github.com/zhedahht/CodingInterviewChinese2/tree/master/03_02_DuplicationInArrayNoEdit
自己代码:https://github.com/quinta2019/Offer/tree/master/03_02_Q_DuplicationInArrayNoEdit