Skip to content

LeetCode287.找到重复数

更新: 6/9/2026 字数: 0 字 时长: 0 分钟

题目链接:287. 寻找重复数

题目大意很好理解,我们只需要从n+1个整数数组中找出唯一一个重复的数字(数字都在[1,n]内),要求不修改 数组 nums 且只用常量级 O(1) 的额外空间。

既然数字都在[1,n]内,那么我们可以对n -> f[n]建立映射关系,比如[1,3,4,2,2]:

0 -> 1

1 -> 3

3 -> 2

2 -> 4

4 -> 2

我们从下标0出发,以f[i]作为新的下标这样去查找,我们可以产生一个类似于链表的序列,然后我们不难发现,这个链表实际上是一个环。

因为如果有重复的数,那么这个链表必然会产生一个多对一的映射,就一定会产生环。那么就转换成了142. 环形链表 II这个题,采用快慢指针的方式,快慢指针的证明方式可以参考题解。

那么这里是数组的形式,如何实现快慢指针呢?我们可以通过链表的走一步和走两步推断出这里的快慢指针走法:

cpp
slow = nums[slow];
fast = nums[nums[fast]];

这样就完成了快慢指针。参考代码如下:

cpp
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int slow = 0, fast = 0;
        slow = nums[slow];
        fast = nums[nums[fast]];
      // 快慢指针,找到相遇点
        while(slow != fast) {
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
      // 一个在头,一个在相遇点,最后一定会在环的入口相遇
        int tmp = 0;
        while(tmp != slow) {
            tmp = nums[tmp];
            slow = nums[slow];
        }
        return tmp;
    }
};