LeetCode 287. Find the Duplicate Number

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 287. Find the Duplicate Number相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 287. Find the Duplicate Number(找重复数字)

[LeetCode] 287. Find the Duplicate Number

LeetCode 287. Find the Duplicate Number

<LeetCode OJ> 287. Find the Duplicate Number

[LeetCode] 287. Find the Duplicate Number 寻找重复数

LeetCode 287. Find the Duplicate Number (找到重复的数字)