LeetCode: Find the Duplicate Number
problem:
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.
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
Subscribe to see which companies asked this question
二分抽屉原理:实际上,我们可以根据抽屉原理简化刚才的暴力法。我们不一定要依次选择数,然后看是否有这个数的重复数,我们可以用二分法先选取n/2,按照抽屉原理,整 个数组中如果小于等于n/2的数的数量大于n/2,说明1到n/2这个区间是肯定有重复数字的。比如6个抽屉,如果有7个袜子要放到抽屉里,那肯定有一个 抽屉至少两个袜子。这里抽屉就是1到n/2的每一个数,而袜子就是整个数组中小于等于n/2的那些数。这样我们就能知道下次选择的数的范围,如果1到n /2区间内肯定有重复数字,则下次在1到n/2范围内找,否则在n/2到n范围内找。下次找的时候,还是找一半。
1 class Solution { 2 public: 3 int findDuplicate(vector<int>& nums) { 4 //二分查找法的运用 5 6 int low=0,high=nums.size()-1; 7 8 9 while(low<=high) 10 { 11 int cnt=0; 12 int middle=low+(high-low)/2; 13 14 for(int i=0;i<nums.size();i++) 15 { 16 if(nums[i]<=middle) 17 cnt++; 18 } 19 20 if(cnt>middle) 21 high=middle-1; 22 else 23 low=middle+1; 24 } 25 26 return low; 27 28 29 } 30 };