题目链接:https://leetcode.com/problems/find-the-duplicate-number/

题目:

nums containing n + 1 integers where each integer is between 1 and n

Note:

  1. You must not
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than 

O(n2)

  1. .
  2. There is only one duplicate number in the array, but it could be repeated more than once.

思路:


不能修改数组所以不能排序,不能用额外的空间所以不能用HashMap,考虑鸽巢原理。数的范围在1~n之间,有n+1个数


猜测重复数为n/2,计算 数组中大于n/2的次数count,如果重复的数在n/2~n之间的话,count应该是大于n-n/2的,搜索范围就减少为[n/2~n]了;否则搜索范围为[1~n/2]。


算法:


public int findDuplicate(int[] nums) {
		int n = nums.length-1,l=1,r=n;
		while(l<r){
			int m = (l+r)/2,count=0,t=0;
			for(int i=0;i<nums.length;i++){
				if(nums[i]>m)
					count++;
				if(nums[i]==m){
					t++;
				}
			}
			if(t>1)
				return m;
			if(count>(n-m)){ //当count大于m应该被大于的次数,则重复值肯定在右边
				l = m+1;
			}else{
				r = m-1;
			}
		}
		return l;
	}