《剑指Offer》面试题3-2:数组中重复的数字

要求:不修改数组找出重复的数字

在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少存在一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。

测试用例:

  1. 长度为n的包含一个或多个重复的数字
  2. 不包含重复的数字
  3. 无效输入测试用例(输入空指针)

本题考点:

  1. 考查对一维数组的理解和编程能力。一维数组在内存中占据连续的空间,因此我们可以根据下标定位对应的元素。
  2. 考查对二分查找算法的理解,并能快速、正确地实现二分查找算法的代码。
  3. 考查沟通能力,只有具备良好的沟通能力,才能充分了解面试官的需求,从而有针对性地选择算法解决问题。

源代码:

/********************************************************************
 * 参数:
 *		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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值