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; } };
时间: 2024-10-12 10:40:13