287. 寻找重复数-floyd判圈算法

问题

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。
假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。
你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。

示例 1:
输入:nums = [1,3,4,2,2]
输出:2

示例 2:
输入:nums = [3,1,3,4,2]
输出:3

分析

Floyd 判圈算法.

假设环长为 L,从起点到环的入口的步数是 a,从环的入口继续走 b 步到达相遇位置,从相遇位置继续走 c 步回到环的入口,则有 b+c=L,其中 L、a、b、c 都是正整数。根据上述定义,慢指针走了 a+b 步,快指针走了 2(a+b) 步。从另一个角度考虑,在相遇位置,快指针比慢指针多走了若干圈,因此快指针走的步数还可以表示成 a+b+kL,其中 k 表示快指针在环上走的圈数。

代码

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n = nums.size();
        if (n == 1) {return nums[0];}
        int l = 0, r = 0;
        while(1) {
            r = nums[nums[r]];
            l = nums[l];
            if (l == r) {
                break;
            }
        }
        l = 0;
        while(1) {
            l = nums[l];
            r = nums[r]; 
            if (l == r) {
                break;
            }
        }
        return l;
    }
};
posted @ 2025-10-02 20:21  saulstavo  阅读(12)  评论(0)    收藏  举报