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;
    }
}
相关推荐
To_OC10 小时前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
鱼鱼不愚与14 小时前
《原来如此 | 第01期:为什么导航软件能预测红绿灯倒计时?》
算法
复杂网络19 小时前
论最小 Agent 计算机的形态
算法
kisshyshy1 天前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
猿人谷2 天前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
复杂网络2 天前
Stable Diffusion 视觉大模型微调技术深度调研
算法
复杂网络2 天前
基于 Stable Diffusion 架构的视觉大模型代表性工作与原理深度解析
算法
MrZhao4002 天前
Agent Loop 如何用 Hook 扩展:权限、日志与工具拦截
算法
MrZhao4002 天前
Agent 为什么需要 Skills:别把所有知识都塞进 system prompt
算法