LeetCode 287. 寻找重复数

https://leetcode-cn.com/problems/find-the-duplicate-number/

这个题跟剑指Offer有一题寻找重复数差不多,但是这个题要求更高一点,要求不能修改原数组的元素,一开始的我要求都没看完就做了,我佛了。。。

    public int findDuplicateFake(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            while ((i + 1) != nums[i]) {
                if (nums[nums[i] - 1] == nums[i]) {
                    return nums[nums[i] - 1];
                }
                int temp = nums[i];
                nums[i] = nums[temp-1];
                nums[temp-1] = temp;
            }
        }
        return 0;
    }

后来想了下,这个只有一个元素是重复出现的,那么其实可以把这个数组看成一条循环链表,LeetCode上有一题叫做寻找循环链表中的环的入口,这个题就有点类似了。

public int findDuplicate(int[] nums) {
int fast = 0, slow = 0;
while(true){
fast = nums[nums[fast]];
slow = nums[slow];
if(slow == fast){
fast = 0;
while (slow != fast){
fast = nums[fast];
slow = nums[slow];
}
return fast;
}
}
}

首先我们定义快慢两个指针,快指针一次走两步,慢指针一次走一步。

如果快慢指针指向的值相同,说明我们可能进入了环。那么我们假设我们所在的地方就是环的其中一个入口,我们让快指针重置,然后每个指针都走一步,直到它两相等即是入口。

这个证明好像是个数学问题,在链表题中有讲解。 

原文地址:https://www.cnblogs.com/ZJPaang/p/12963527.html