问题:
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+1个1到n之间的整数,只有一个重复的数的话,要求找出这个唯一重复的数,满足如下条件:
1.不能改变这个数组(比如不能重新排序)
2.只能用连续的空间复杂度为o(1)的空间
3.时间复杂度小于o(n2)
4.虽然只有一个重复的数,但这个数可以重复多次
思路:
利用折半查找的思想,因为是1到n之间的数,令low=1,high=n,先求得一个中间值mid=(low+high)/2,遍历一遍数组,求出小于mid的元素的个数c,若c小于等于mid,则重复的数大于mid,令left=mid+1,重复以上步骤,反之则小于等于mid,令right=mid,重复以上步骤。随着范围的缩小,当low>=high时,可求出重复的数。
1 class Solution { 2 public: 3 int findDuplicate(vector<int>& nums) { 4 int n = nums.size()-1; 5 int low = 1, high= n; 6 int mid = 0; 7 while(low<high) { 8 mid = (low+high)/2; 9 int c= count(nums, mid); 10 if(c<=mid) { 11 low = mid+1; 12 } else { 13 high = mid; 14 } 15 } 16 return low; 17 } 18 19 int count(vector<int>& nums, int mid) { 20 int c =0; 21 for(int i=0; i<nums.size(); i++) { 22 if(nums[i]<=mid) c++; 23 } 24 return c; 25 } 26 };