leetcode题解----287. 寻找重复数(二分法)

给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
示例 1:

输入: [1,3,4,2,2]
输出: 2

示例 2:

输入: [3,1,3,4,2]
输出: 3

说明:

不能更改原数组(假设数组是只读的)。
只能使用额外的 O(1) 的空间。
时间复杂度小于 O(n2) 。
数组中只有一个重复的数字,但它可能不止重复出现一次。

题目链接(leetcode)

思路:这道题很经典,我面试的时候被问过,有好多种不同的做法,但是被限制了好多条件之后,这些做法就不能用了。
我们先从最笨的方法开始,枚举1 - n,看一看它在数组中出现了几次,如果出现的次数超过1次,说明它是重复的数字,这样直接暴力的话复杂度就是O(n^2)。
我们可以进行优化一下,两层循环,里面那一层计数是优化不了,我们可以考虑优化一下外层的循环。如果数字x出现的次数大于1,说明x重复了,同样如果数字x到y之间出现的次数大于(y-x+1)次,那么说明重复的数字必然出现在x到y之间。
由此我们可以很容易地想到二分法,计数1到n/2,如果出现的次数大于n/2,说明重复的数字在区间1-(n/2)之间,否则重复的数字出现在右边。

参考代码:

class Solution {
    public int findDuplicate(int[] nums) 
    {
    	int l = 1, r = nums.length - 1;
    	while(l < r)
    	{
    		int mid = (l + r) / 2;
    		int cnt = 0;
    		for(int i = 0;i < nums.length;i++)
    			if(nums[i] <= mid && nums[i] >= l)
    				cnt++;
    		if(cnt > (mid - l + 1))
    			r = mid;
    		else
    			l = mid + 1;
    	}
    	return l;
    }
}
发布了72 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41022094/article/details/103928830