码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 287. Find the Duplicate Number

时间:2016-05-21 21:50:27      阅读:458      评论:0      收藏:0      [点我收藏+]

标签:

Find the Duplicate Number | LeetCode OJ
https://leetcode.com/problems/find-the-duplicate-number/

这个题目属于编码比较简单但解法分析过程比较复杂。

 

首先,把1~n放入0~n个元素,必定有两个或以上元素重复。数字里没有0,所以从下标0出发不会再回到最初的元素0。

假设当前的下标为x,下一步的下标为f(x),若f(x) = A[x], 也即每次跳到一个元素,则下一步移动到当前元素值对应的元素下标。我们来证明这样的移动存在环:

假设重复的元素值为x.

假设x存在于A[1..n]中,A[i] 和A[j]的值为x。除去i,j,A[1..n]还剩下n-2个元素,若A[x]值为i,j,x之一,显然这是一个环。假设A[x]的值为k,k!=x && k!=i && k!=j,则剩下n-3个元素。因为重复的元素只有x,所以剩下的元素值不能为k,这样我们只有n-4个不重复的值可用,如果要填入n-3个元素,或者这n-4个元素有重复,这和假设矛盾,或者只能填入i,j,x之一。这样就形成了一个环。

A[0]=x的情况证明也类似。

既然证明了这种遍历方式存在环,我们就可以套用 Linked List Cycle II 的思路来找到环的起点。此处不赘述。

详细分析可以参考这篇:http://keithschwarz.com/interesting/code/?dir=find-duplicate

 代码如下:

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        if(nums.size() <= 1){
            return -1;
        }
        
        int fast = 0, slow = 0;
        do{
            fast = nums[nums[fast]];
            slow = nums[slow];
        }while(fast != slow);
        
        fast = 0;
        while(fast != slow){
            fast = nums[fast];
            slow = nums[slow];            
        }
        
        return slow;
    }
};

 

 

LeetCode 287. Find the Duplicate Number

标签:

原文地址:http://www.cnblogs.com/polymorphism/p/5496526.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!