leetcode287

目前最新的题目吧。

Find the Duplicate Number

官方给的难度是hard,但感觉其实通过挺简单的。

这道题目的意思是在n+1大小的数组中有范围在1~n的数

要求找出相同的一个数。

限制比较多:

1.不能修改数组

2.时间复杂度要求

3.不能有多余空间


直到写这篇博客前,才注意原来不能修改数组,不过我先排序,再在有序数组中找到重复数字的代码居然通过了。。

先给出代码,下来找到不修改数组的方法后再来更博:

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int i;
        for(i=0;i<nums.size();i++)
        {
            if(nums[i]==nums[i+1])
                break;
        }
        return nums[i];
    }
};


=============================2015/09/30晚更新=================================================

发现这道题目的真实限制之后,久久不能释怀。不能移动数组这个约束,让我难受了好几天。

在论坛学习到了大神的思路(鸽巢原理):

n个笼子(表示数字范围1~n),却有n+1只鸽子(表示数组大小,即有n+1个数,每只鸽子表示一个数),则必然有一个数字(笼子)对应两只及以上的鸽子(数)

思路,首先找到这些数字的中数,由于数字是1~n,一开始这个数字时 (n+1)/2

然后拿数组中的数与中数比较,当比中数小的数>中数 (这个道理举个例子就能看清):则说明重复的数在中数的左边,即比中数小

这样我们将重新对中数左边的部分进行上述比较(这里实际上隐式的维护了一个1~n的数组)。

还是看代码比较清晰:

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
		int i;
		int vecLen = nums.size();
		int low = 1;
		int high = vecLen-1;
		while(low < high)
		{
			int mid = (high  + low) / 2;		
			int count = 0;
			for(i=0;i<vecLen;i++)
			{
				if(nums[i]<=mid)
					count ++;
			}
			if(count > mid)
			{
				high = mid;
			}
			else
			{
				low = mid+1;
			}
		}
		return low;
    }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值