LeetCode Find the Duplicate Number 找重复出现的数(技巧)

 

 

题意:

  有一个含有n+1个元素的数组,元素值是在1~n之间的整数,请找出其中出现超过1次的数。(保证仅有1个出现次数是超过1的数)

 

 

思路:

  方法一:O(nlogn)。根据鸽笼原理及题意,每次如果<=k的数超过了k个,那么答案必定在[1,k]。可以用二分枚举答案来解决。

 1 bool left(vector<int>& nums,int tar)//是否在左边
 2 {
 3     int cnt=0;
 4     for(int i=0; i<nums.size(); i++)    
 5         if(nums[i]<=tar)    
 6             cnt++;
 7     return cnt>tar;
 8 }
 9 
10 int findDuplicate(vector<int>& nums)
11 {
12     int L=1, R=nums.size()-1;
13     while(L<R)
14     {
15         int mid=R-(R-L+1)/2;
16         if( left(nums,mid)==true )    R=mid;
17         else    L=mid+1;
18     }
19     return R;
20 }
AC代码

 

 

  方法二:O(n)。将数组nums看成是一个链表,next[i]表示点i的后继(0也是一个点,因为0也是下标)。根据题意,此链表必定有且仅有一个简单环存在,这样就类似于Linked List Cycle II ,只是会多余出部分的链,但是这不会影响到这个模型,从0点出发依然存在这样的一个模型,只是环的接口处不会是0而已。要注意两个指针的起始位置,必须保证fast=2*slow。

 1 class Solution {
 2 public:
 3     int findDuplicate(vector<int>& nums)
 4     {
 5         int slow=0, fast=nums[0];
 6         while(fast!=slow)
 7         {
 8             slow=nums[slow];
 9             fast=nums[nums[fast]];
10         }
11         fast=0;
12         slow=nums[slow];
13         while(fast!=slow)
14         {
15             slow=nums[slow];
16             fast=nums[fast];
17         }
18         return fast;
19     }
20 };
AC代码

 

posted @ 2015-10-30 20:19  xcw0754  阅读(182)  评论(0编辑  收藏  举报