LeetCode 287 寻找重复数字

题目

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。

示例 1:

复制代码
输入:nums = [1,3,4,2,2]
输出:2

示例 2:

复制代码
输入:nums = [3,1,3,4,2]
输出:3

示例 3 :

复制代码
输入:nums = [3,3,3,3,3]
输出:3

思路解析

实际上最简单的做法就是一次遍历即可,用Set维护,看是否出现过,这样很容易写,但是要额外的空间花销,时间空间都是O(n)

还有更省空间的做法,就是我们把nums当作链表来维护

数组:nums = [1,3,4,2,2]

我们把:索引 0 -> nums[0] 索引 1 -> nums[1] ...

理解为:

0 → nums[0] 1 → nums[1]

即:

i -> nums[i]

那么这个数组就变成:

0 → 1 → 3 → 2 → 4 → 2 → 4 → 2 ...

你会发现:

数字 2 出现重复

图结构中就形成了一个环

那么就可用链表找循环入口思路解决了

第一步:找相遇点(判断是否有环)

慢指针一次走一步

快指针一次走两步

如果存在环:

fast == slow

必然会相遇


第二步:找环入口

数学证明结论:

相遇后,把 slow 放回起点

slow 和 fast 每次走一步

再次相遇的地方就是环入口

环入口 = 重复数字

为什么第二次相遇一定是入口?(核心数学推导)

设:

a = 起点到环入口距离 b = 环入口到相遇点距离 c = 环剩余部分

当第一次相遇时:

slow 走了 a + b fast 走了 2(a + b)

因为 fast 比 slow 多走一圈:

2(a + b) = a + b + k(b + c)

化简得:

a = k(b + c) - b

可得:

a = c + (k-1)(b+c)

说明:

从起点走 a 步

等价于从相遇点走 c 步

而 c 正是:

相遇点到环入口的距离

因此:

slow 从头走 fast 从相遇点走

他们一定在入口相遇

代码

java 复制代码
class Solution {
    public int findDuplicate(int[] nums) {

        // 慢指针:每次走一步
        int slow = 0;

        // 快指针:每次走两步
        int fast = 0;

        // 第一阶段:找到相遇点
        // do-while 是因为必须先走一步
        // 不能直接比较 0 == 0
        do {
            // slow 走一步
            slow = nums[slow];

            // fast 走两步
            fast = nums[nums[fast]];

        } while (fast != slow);  // 相遇说明进入环

        // 第二阶段:寻找环入口
        // 将 slow 放回起点
        slow = 0;

        // slow 和 fast 同速前进
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }

        // 再次相遇的位置就是环入口
        // 也就是重复数字
        return slow;
    }
}
相关推荐
斯内科5 小时前
四胞胎素数:找出‌个位数分别是 1、3、7、9‌,且‌十位及更高位数字完全相同‌的质数,例如 11、13、17、19
算法·质数·素数·四胞胎素数
Hello.Reader5 小时前
算法基础(十二)——主方法:快速求解常见递归式
算法
香蕉鼠片6 小时前
面试过程中被问懵
面试·职场和发展
小O的算法实验室6 小时前
2026年IEEE TITS,面向按需外卖配送调度的特定问题知识与基于学习元启发式算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
加勒比海带666 小时前
目标检测算法——农林行业数据集汇总附下载链接【Plant】
大数据·图像处理·人工智能·算法·目标检测
洛水水6 小时前
【力扣100题】23. 螺旋矩阵
算法·leetcode·矩阵
影sir6 小时前
不同测试数据下,该如何选择算法
算法·深度优先
潇湘散客6 小时前
CAX软件插件化设计实现牛刀小试
c++·算法·图形学·opengl
速易达网络7 小时前
2026,视觉算法正在经历一场静默革命
算法
WBluuue7 小时前
Codeforces 1094 Div1+2(ABCDE)
c++·算法