题目链接:https://leetcode.com/problems/find-the-duplicate-number/
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than
O(n2)
. - There is only one duplicate number in the array, but it could be repeated more than once.
思路:这题有一个定理叫做鸽笼原理,大意就是n个东西放到m个容器中,如果n > m,那么必然有一个容器包含多于一个东西。
而这题把数据范围限制在1-n之间也是别有用意,这样我们就可以用二分查找来不断缩小范围来找到重复的数。
我们使用二分查找先确定一个中间值mid,然后统计整个数组,看比mid小的数是否比mid多,如果多的话,说明重复的值就在[left, mid-1]之间,否则就在[mid+1, right]之间。
代码如下:
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int left = 1, right = nums.size();
while(left <= right)
{
int mid = (left + right)/2, cnt = 0;
for(auto val: nums) if(val <= mid) cnt++;
cnt <= mid? left=mid+1: right=mid-1;
}
return left;
}
};