当前位置: 首页 > news >正文

LeetCode 287. 寻找重复数:从直觉到 Floyd 判圈的完整推导

一、题目描述

给定一个长度为n + 1的数组nums,其中:

  • 所有数字都在[1, n]范围内

  • 只有一个重复的数字(但可能重复多次)

请找出这个重复的数字。

⚠️限制条件(重点)

  • ❌ 不能修改原数组

  • ✅ 只使用O(1)​ 额外空间

示例:

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

二、为什么这题“看起来简单但很难”

如果你允许修改数组,这题很简单:

方法

思路

问题

排序

相邻比较

修改数组 ❌

HashSet

记录出现次数

额外空间 ❌

但题目明确要求:

不能改数组 + O(1) 空间

👉 于是我们必须把“数组本身”当成某种结构来推理


三、核心洞察:把数组看成「链表」

1️⃣ 关键抽象

数组下标:0 ~ n

数组取值:1 ~ n

我们可以把数组理解成一个映射函数

f(i) = nums[i]

从任意位置i出发,不断执行:

i → nums[i] → nums[nums[i]] → ...

👉 这本质上是一条链表路径


2️⃣ 为什么一定有环?

  • 节点数:n + 1

  • 值域:1 ~ n(没有 0)

➡️必然存在某个节点被指向多次

➡️必然形成环

而:

环的入口,就是那个重复的数字


四、Floyd 判圈算法(快慢指针)

这正是Linked List Cycle II​ 的翻版。

Step 1:找相遇点(快慢指针)

slow = nums[slow] fast = nums[nums[fast]]

最终它们一定在环内某点相遇


Step 2:找环的入口(重复数)

将其中一个指针重置到起点:

slow = 0

然后同步前进:

slow = nums[slow] fast = nums[fast]

再次相遇的位置,就是重复的数字


五、结合例子理解(非常关键)

nums = [1,3,4,2,2]为例:

索引路径:

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

结构如下:

0 → 1 → 3 → 2 ↓ 4
  • 环:2 → 4 → 2

  • 环的入口:2

  • ✅ 答案就是2


六、为什么这个方法一定正确?

阶段

目的

快慢指针相遇

证明存在环

重置一个指针

对齐起点与环入口距离

同步移动

数学上必然在入口相遇

这是一个严格可证明​ 的算法,不是“玄学”。


七、Java 实现(面试标准版)

class Solution { public int findDuplicate(int[] nums) { int slow = 0, fast = 0; // Step 1: 找到相遇点 do { slow = nums[slow]; fast = nums[nums[fast]]; } while (slow != fast); // Step 2: 找到环的入口(重复数) slow = 0; while (slow != fast) { slow = nums[slow]; fast = nums[fast]; } return slow; } }

八、复杂度分析

指标

数值

时间复杂度

O(n)

空间复杂度

O(1) ✅

是否修改数组

完全满足题目所有限制。


九、易错点总结(面试高频)

不要尝试排序 / HashMap / 计数数组

错误思路

原因

排序

修改数组

HashSet

额外空间

二分

可行但不是最优直观解

面试加分点

“这题本质是一个隐式链表 + Floyd 判圈问题。”


十、总结一句话

解法

特点

暴力 / 排序

❌ 不满足限制

哈希表

❌ 空间超限

Floyd 判圈

✅ 最优解

📌记忆口诀

数组当链表,快慢找相遇,重置再同步,入口即答案

http://www.gsyq.cn/news/1602600.html

相关文章:

  • Python的__init_subclass__验证
  • 操作系统内存管理
  • 猫抓:如何解决网页视频无法下载的三大难题?
  • 哈夫曼编码和香农-范诺编码的性能对比 P124302171陈新阳
  • 欺诈检测化技术行为分析模型与实时规则引擎
  • Bitget发布Web3人才报告:54%求职者受困「经验门槛」,AI与区块链融合成最热职业方向
  • 深度掌控AMD Ryzen:专业级SMU调试工具完全指南
  • TestDisk终极指南:5步快速恢复丢失分区与数据
  • Paperclip - 多Agent编排管理平台详细介绍
  • Hermes - AI Agent 运行时框架详细介绍
  • 零食折扣店收银系统哪个牌子好?扫码快、上手简单才是关键
  • esp32开发与应用(esp和wch芯片的配合)
  • AFE5808A超声模拟前端芯片ADC与VCA寄存器配置实战指南
  • 为什么选择OmenSuperHub?一个免费开源工具彻底解决惠普游戏本性能限制问题
  • Nginx从入门到精通:一文搞懂这款高性能Web服务器的核心原理与实战配置
  • 完成发射班的焊接及调试
  • 【Flutter零基础入门 | Day03】常用功能与滚动组件
  • 安全组网建设怎么选
  • Burp Suite Repeater实战指南:HTTP请求精细调试与渗透测试技巧
  • 推荐系统基础算法简介
  • 【RuoYi-Vue-Plus】源码探秘:OSS配置从数据库到Redis的缓存同步机制
  • Win11Debloat:免费快速的Windows系统优化终极方案
  • Qt 铁甲阅读器-搜索
  • 本地离线批量 OCR 实战:证件、发票、铭牌一键提取结构化信息
  • 如何在Amlogic电视盒上安装Debian系统:2025年终极开源解决方案
  • 英雄联盟皮肤库终极指南:一站式获取所有官方皮肤与炫彩资源
  • 3分钟掌握Chrome画中画扩展:免费提升多任务效率的终极指南
  • 惠普暗影精灵性能控制终极指南:OmenSuperHub开源工具完全解析
  • Superpowers - 编码Agent 工程技能插件集详细介绍
  • Android13文件访问权限重构:从MANAGE_EXTERNAL_STORAGE到细粒度媒体权限的实战解析