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;
    }
}
相关推荐
地平线开发者2 小时前
profiler debug 工具用法与高一致性策略
算法·自动驾驶
编程大师哥2 小时前
匿名函数 lambda + 高阶函数
java·python·算法
我叫袁小陌2 小时前
算法解题思路指南
算法
地平线开发者2 小时前
Conv+BN+Add+ReLU 融合机制简介
算法·自动驾驶
yuanyuan2o23 小时前
模型预训练:Hugging Face Transformers 基础
算法·ai·语言模型·自然语言处理·nlp·深度优先
杨充3 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
妄想出头的工业炼药师3 小时前
GS slam mono
算法·开源
_日拱一卒4 小时前
LeetCode:207课程表
java·数据结构·算法·leetcode·职场和发展
jiayong235 小时前
AI架构师面试题库 - 完整汇总文档
人工智能·面试·职场和发展