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

【Hot 100 刷题计划】 LeetCode 142. 环形链表 II | C++ 哈希表直觉解法

LeetCode 142. 环形链表 II

📌 题目描述

题目级别:中等

给定一个链表的头节点head,返回链表开始入环的第一个节点。 如果链表无环,则返回null
不允许修改 链表。

  • 示例 1:
    输入:head = [3,2,0,-4],pos = 1
    输出:返回索引为 1 的链表节点
    解释:链表中有一个环,其尾部连接到第二个节点。

💡 解法一:哈希表备忘录

想要找到“环的入口”,最直接的想法就是“留下脚印”。
我们在遍历链表的过程中,把路过的每一个节点的指针都记在哈希表(HashSet)里。
不断往前走,每走到一个新节点,都先去查一下表:

  1. 如果表中不存在,就把当前节点记录下来,继续往下走。
  2. 如果走到某个节点,发现它已经在哈希表里了!那么毫无疑问,这个节点就是我们绕了一圈后第一次重新踏足的地方,它就是环的入口节点
  3. 如果一路走到nullptr,说明这是一条直线,直接返回null

💻 C++ 代码实现 (哈希表法)

classSolution{public:ListNode*detectCycle(ListNode*head){// 使用 unordered_set 记录已经访问过的节点unordered_set<ListNode*>seen;while(head!=nullptr){// 如果当前节点已经被访问过,它就是环的入口if(seen.count(head))returnhead;// 记录当前节点seen.insert(head);// 向后移动head=head->next;}// 走到了链表尽头,无环returnnullptr;}};

💡 解法二:Floyd 判环算法 (龟兔赛跑进阶)

这道题是考察数学推导的经典之作。我们可以用快慢指针分两阶段解决:

阶段 1:判断是否有环,并找到相遇点
定义快指针fast(每次 2 步) 和慢指针slow(每次 1 步)。如果它们在某处相遇了,说明一定有环。

阶段 2:寻找环的入口 (数学推导)
设起点到入口的距离为xxx
设入口到相遇点的距离为yyy
设相遇点到入口的剩余距离为zzz

  • slow走了x+yx + yx+y
  • fast走了x+y+n(y+z)x + y + n(y + z)x+y+n(y+z)
    因为fast的速度是slow的两倍:
    2(x+y)=x+y+n(y+z)2(x + y) = x + y + n(y + z)2(x+y)=x+y+n(y+z)
    化简得到:
    x=(n−1)(y+z)+zx = (n - 1)(y + z) + zx=(n1)(y+z)+z
    这个极其漂亮的公式告诉我们:起点到环入口的距离xxx,刚好等于相遇点走到环入口的距离zzz(再加上几圈闲逛)。

行动指南:
当两指针相遇后,我们把其中一个指针扔回起点,另一个留在相遇点。然后两人速度保持一致(都每次走 1 步)。当他们再次相遇时,相交的节点必定是环的入口!


💻 C++ 代码实现 (快慢指针最优解)

classSolution{public:ListNode*detectCycle(ListNode*head){if(!head||!head->next)returnnullptr;ListNode*slow=head;ListNode*fast=head;// 阶段 1:快慢指针寻找相遇点while(fast&&fast->next){slow=slow->next;fast=fast->next->next;// 如果相遇了,进入阶段 2if(slow==fast){// 将其中一个指针重置到头部ListNode*p1=head;ListNode*p2=slow;// 两人以相同速度前进,相遇点即为环入口while(p1!=p2){p1=p1->next;p2=p2->next;}returnp1;}}returnnullptr;}};
http://www.cnnetsun.cn/news/2114685.html

相关文章:

  • 保姆级教程:用群晖DSM 7.2的Synology Photos,打造个人专属的‘朋友圈’相册
  • DeepSeek V4技术实力到底怎么样?三大维度全面领跑的技术深度分析
  • 【AHC】在 Kubernetes 环境中,AHC 如何应对服务短暂不可用(如 Pod 重启)?
  • SI理论基础
  • 嵌入式 ARM架构与汇编
  • Linux(静态动态库,缓冲区输出问题,fork()父子进程,逻辑物理地址,僵死进程,孤儿进程,主函数参数)
  • 多层 FPC 叠构设计:柔性电路板的 “骨架工程” 与性能基石
  • WASM模块在Docker中无法热更新?手把手修复OCI镜像层绑定缺陷,实现亚秒级边缘函数灰度发布(附patch源码与e2e测试脚本)
  • 终极指南:用Ryujinx模拟器在PC上畅玩任天堂Switch游戏
  • 书匠策AI:毕业论文“智造”新引擎,解锁学术写作新姿势
  • PostgreSQL 高负载 Load Average 暴涨 | BufferMapping LWLock 锁竞争 完整排查优化实战
  • reactor
  • 2026年Geo专家综合能力与执行效果深度评测:AI时代下的信任重构
  • 深度解析开源自动化框架:从图像识别到黑盒测试的完整技术实践
  • Trippy网络诊断工具深度解析:现代网络故障排查的专业利器
  • Outfit字体:现代设计的无声革命者
  • VS Code Dev Containers 优化终极指南(2024年Linux/macOS/WSL3实测版):从22秒冷启动到3.1秒的全链路调优路径
  • Unity GPU 波前(Wavefront / Warp)对 Shader 设计的影响
  • 终极指南:3步快速解密QQ聊天记录数据库
  • 智能办公新方式:OpenClaw 一键部署与配置
  • 3分钟快速部署i茅台自动预约系统:告别手动抢购的Java神器
  • 语义分割调参避坑:你的ASPP模块dilation rate选对了吗?PyTorch实验对比告诉你答案
  • Radeon ProRender Blender插件实战指南:三步实现专业级渲染效果
  • PitchDetect:基于Web Audio API的实时音高检测完整解决方案
  • 只要中一个,就说明你已经找到了对抗加班文化的正确方法
  • VTube Studio终极指南:如何通过API打造个性化虚拟主播体验
  • KUKA iiwa机器人FRI控制实战:手把手教你用Java在Sunrise Workbench 1.7里写第一个实时运动程序
  • 基于MCP协议的AI智能体工具集成平台:Klavis AI架构与应用实践
  • Go语言构建高可用分布式任务调度框架:从Cron到Copaw的实践
  • 5分钟终极指南:如何用untrunc免费快速修复损坏的MP4/MOV视频文件