leetcode之Find the Duplicate Number 问题

问题描述:

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.

问题来源Find the Duplicate Number (具体地址:https://leetcode.com/problems/find-the-duplicate-number/#/description)

思路:在这就给出最好的解法了,其他的二分查找啥的就不介绍了哈。这道题首先它的原理是组合数学当中非常著名的 鸽巢原理,也叫抽屉原理鸽巢原理。有n + 1个数,但是只包含1~n之间的数,所以必然会有一个数字是重复的。现在我们该怎么找出它呢?这道题如果第一次见,还是挺难想到的, 我们可以定义两个指针,一个定义为fast,它每次走两步,而另一个指针定义为slow,它每次走一步。下面举个例子来说明一下具体两个指针咋走的:
index(数组索引)i:0  1  2  3  4  5  6  7  8
具体数值nums[i]:2  3  5  6  1  7  8  1  4
在这假定1是重复的,正确走的每一步规则是i = nums[i],所以正确的走法为:2->5->7->1->3->6->8->4->1->...,然后就开始循环了,所以快指针fast走的是2->7->3->8->1>3->8....,慢指针slow走的就是上面的一步一步的走的,就不在这列了。所以这样下去, 一定会在环中的某个点上相遇的 ,具体可以参考 cycle detection或者叫做cycle finding,然而我们要求的不是这个结果,我们要求的是重复的数字,也就是这个例子当中的1,即环的入口。
如何求环的入口:
上面咱们不是已经求出它们再环中相遇的位置了嘛,保留一个指针slow或者fast都可以,然后让其中一个(在这我采用的是finder)从数组的开始位置开始走,此时留在环中的指针同时走,而且这次咱们都走一步,最后再次相遇的时候找到的就是环的入口。
具体有些人直接懵逼了,觉得你说咋相遇就相遇了呢?给出我画的一个简易版的图

代码:


体会:这道题还是很有意义的,第一次见到的话还是比较难想到这种解法的。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值