题目:给定一个长度为 n+1的数组nums,数组中所有的数均在 1~n的范围内,其中 n≥1。请找出数组中任意一个重复的数,但不能修改输入的数组。
如果只能使用 O(1)的额外空间,该怎么做呢?
思路:存在n+1个数值,数值的范围为1~n,所以必定存在重复数值;
采用递归+抽屉思想 ;
设数值区间为[l,r],取数值终点mid,统计[l,mid]区间的数值数是否等于mid-l+1;
不等的话则重复数值在此区间内,在此区间继续进行递归二分,直到l=r,此时r即为重复数值;
如果相等的话则在右区间[mid+1,r]内进行递归二分。
C++代码如下
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int n = nums.size();
for (auto x : nums)
{
if (x<0 || x>n - 1)return -1;
}
for (int i = 0; i < n; i++)
{
while (i != nums[i] && nums[i] != nums[nums[i]])
{
swap(nums[i], nums[nums[i]]);
}
if (i != nums[i] && nums[i] == nums[nums[i]])return nums[i];
}
return -1;
}
};