解密链表环的起点:LeetCode 142 题

解密链表环的起点:LeetCode 142 题

解密链表环的起点:LeetCode 142 题

视频地址

因为想更好的为大佬服务,制作了同步视频,这是Bilibili的视频地址

🌟 引言

链表环检测问题在C++中同样是一个经典面试题。本文将用C++实现LeetCode 142题"环形链表II"的解决方案,深入讲解快慢指针算法的原理和实现细节。

🔍 问题描述

给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回 nullptr

🧠 解题思路回顾

快慢指针算法

  1. 使用两个指针:slow每次走一步,fast每次走两步
  2. 如果两指针相遇,说明链表有环
  3. 将其中一个指针重置到链表头,然后两指针以相同速度前进
  4. 再次相遇的位置就是环的起点

数学原理

设:

  • 链表头到环起点距离:a
  • 环起点到相遇点距离:b
  • 相遇点到环起点距离:c

则有:

  • 第一次相遇时:slow走了a+bfast走了a+b+c+b
  • 因为fast速度是slow的两倍:2(a+b) = a+2b+c
  • 推导得:a = c

💻 C++代码实现

/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */classSolution{public: ListNode *detectCycle(ListNode *head){// 边界条件处理if(head ==nullptr|| head->next ==nullptr){returnnullptr;} ListNode *slow = head; ListNode *fast = head;// 第一阶段:检测是否有环while(fast !=nullptr&& fast->next !=nullptr){ slow = slow->next; fast = fast->next->next;if(slow == fast){break;// 相遇说明有环}}// 检查是否因为无环退出循环if(fast ==nullptr|| fast->next ==nullptr){returnnullptr;}// 第二阶段:寻找环起点 slow = head;// 重置慢指针到头部while(slow != fast){ slow = slow->next; fast = fast->next;}return slow;// 相遇点即为环起点}};

🛠 代码解析

数据结构定义

structListNode{int val; ListNode *next;ListNode(int x):val(x),next(NULL){}};

这是LeetCode标准的链表节点定义,包含一个整数值和指向下一个节点的指针。

算法实现细节

寻找环起点

slow = head;// 重置慢指针到头部while(slow != fast){ slow = slow->next; fast = fast->next;}

根据数学推导,两指针以相同速度前进,再次相遇点即为环起点。

无环检查

if(fast ==nullptr|| fast->next ==nullptr){returnnullptr;}

如果因为快指针无法前进而退出循环,说明无环。

环检测阶段

while(fast !=nullptr&& fast->next !=nullptr){ slow = slow->next; fast = fast->next->next;if(slow == fast){break;// 相遇说明有环}}

快指针每次走两步,慢指针每次走一步,直到相遇或快指针无法前进。

指针初始化

ListNode *slow = head; ListNode *fast = head;

快慢指针都从头节点开始。

边界条件处理

if(head ==nullptr|| head->next ==nullptr){returnnullptr;}

处理空链表或单节点链表的特殊情况。

🚀 性能分析

  • 时间复杂度:O(n)
    • 最坏情况下需要遍历链表两次
  • 空间复杂度:O(1)
    • 只使用了固定数量的指针变量

🐞 常见问题与调试

常见错误

  1. 初始条件处理
    忘记处理空链表或单节点链表的情况。
  2. 指针重置错误
    在第二阶段错误地重置了快指针而不是慢指针。

空指针访问

while(fast !=nullptr&& fast->next !=nullptr)

必须同时检查fastfast->next,否则可能访问空指针的next成员。

调试技巧

  1. 小规模测试
    • 无环链表:1->2->3->null
    • 有环链表:1->2->3->4->2(环在节点2)
  2. 边界测试
    • 空链表
    • 单节点自环链表
    • 双节点互相指向的链表

打印指针地址

cout <<"Slow: "<< slow <<" Fast: "<< fast << endl;

帮助跟踪指针移动情况。

📊 复杂度对比表

方法时间复杂度空间复杂度适用场景
哈希表法O(n)O(n)需要简单实现时
快慢指针O(n)O(1)需要节省空间时

🌈 总结

通过C++实现的快慢指针算法,我们能够高效地解决链表环检测问题。关键在于:

  1. 理解快慢指针相遇的数学原理
  2. 正确处理边界条件和指针访问

分两个阶段实现:环检测和环起点定位

解密链表环的起点:LeetCode 142 题

这种方法不仅高效(O(n)时间,O(1)空间),而且体现了算法设计的巧妙之处。掌握这个技巧,你就能轻松应对链表相关的各种环检测问题了!

Read more

面向复杂路口的Apollo决策算法语义理解模块设计与仿真

面向复杂路口的Apollo决策算法语义理解模块设计与仿真 引言 复杂路口是城市道路自动驾驶最具挑战性的场景之一,其复杂性源于多模态交通参与者(机动车、非机动车、行人)、非结构化交通规则(让行标志、地面标线、交警手势)、动态交互博弈(抢行、礼让、冲突消解)的高度耦合。Apollo决策层作为连接环境感知与运动规划的核心枢纽,其对复杂路口的语义理解能力直接决定了自动驾驶车辆的行驶安全性与通行效率。传统基于规则的决策方法在处理此类场景时,常因语义信息提取不完整、交互关系建模粗糙、规则覆盖度不足等问题,导致决策逻辑僵化或误判。 语义理解模块通过深度解析路口场景的多维度语义信息(如交通参与者意图、交通规则约束、空间拓扑关系),为决策层提供结构化的场景认知结果,是实现从"感知数据"到"决策知识"转化的关键桥梁。本文聚焦Apollo决策算法体系,设计面向复杂路口的语义理解模块,构建包含场景要素提取、语义关系建模、意图推理、规则映射四大核心功能的仿真验证框架,通过多场景仿真实验验证模块的有效性,为提升Apollo在复杂路口的决策鲁棒性提供技术支撑。 技术背景 2.1 Apollo决策层架构

By Ne0inhk
利用 Python 爬虫进行跨境电商数据采集

利用 Python 爬虫进行跨境电商数据采集

* 1 引言 * 2 代理IP的优势 * 3 获取代理IP账号 * 4 爬取实战案例---(某电商网站爬取) * 4.1 网站分析 * 4.2 编写代码 * 4.3 优化代码 * 5 总结 1 引言 在数字化时代,数据作为核心资源蕴含重要价值,网络爬虫成为企业洞察市场趋势、学术研究探索未知领域的重要技术手段。然而爬虫实践中常面临技术挑战,例如某电商企业通过爬虫获取竞品数据时,因高频请求触发目标平台 IP 封锁机制导致采集中断。IP 代理在网络爬虫中发挥关键作用:通过分布式请求分散访问压力,可规避单 IP 高频访问限制并突破地域内容获取限制;同时能隐藏真实 IP 地址降低法律风险,模拟多用户行为特征优化反爬虫策略,有效平衡数据获取需求与网络访问规则。这种技术工具通过突破技术限制、提升采集效率、保障数据安全等多维价值,成为网络爬虫体系中的重要组成部分。本文将介绍代理IP在网络爬虫中的重要性,并结合实际应用。 2 代理IP的优势

By Ne0inhk

Python GUI开发革命:CustomTkinter完整指南

Python GUI开发革命:CustomTkinter完整指南 【免费下载链接】CustomTkinterA modern and customizable python UI-library based on Tkinter 项目地址: https://gitcode.com/gh_mirrors/cu/CustomTkinter CustomTkinter是一个基于Python Tkinter的现代化UI库,为传统Tkinter注入了全新的生命力。它提供了一系列美观、现代化且完全可定制的组件,支持自动适配系统外观模式和高DPI缩放,让Python桌面应用开发变得简单而优雅。 为什么选择CustomTkinter? 在Python GUI开发领域,Tkinter虽然易用但界面陈旧,而PyQt等库学习曲线陡峭。CustomTkinter完美解决了这一痛点——它保留了Tkinter的简单语法,同时提供了媲美现代桌面应用的视觉效果。无论你是初学者还是经验丰富的开发者,都能在几分钟内创建出专业级的界面。 惊艳界面效果展示 CustomTkinter能够创建出令人惊叹的现代化

By Ne0inhk
Python调用PubMed API实战:构建医学文献搜索系统【附完整代码】

Python调用PubMed API实战:构建医学文献搜索系统【附完整代码】

🎯 背景与需求 作为医疗健康领域的开发者,我们经常需要从PubMed检索大量医学文献。手动搜索效率低下,而构建自动化的文献检索系统成为刚需。 典型应用场景: * 🏥 临床决策支持系统需要快速检索相关文献 * 📊 科研数据分析需要批量获取文献元数据 * 📝 医学知识库构建需要持续更新文献信息 * 🤖 AI医疗助手需要实时检索最新研究进展 核心技术挑战: 1. PubMed API的调用规范和限流策略(3 req/s vs 10 req/s) 2. XML/JSON数据格式的解析和结构化存储 3. 批量检索时的性能优化和错误处理 4. 医学术语的标准化和中英文映射 💡 技术方案选型 在调用PubMed API时,我们有三种主流技术方案: 方案对比 方案技术栈优点缺点适用场景方案1:原生HTTP请求requests + XML解析轻量灵活,完全自主控制需手动处理XML,限流逻辑复杂学习研究、定制化需求方案2:Biopython库Bio.Entrez模块封装完善,自动限流依赖较重,更新较慢生物信息学项目方案3:集成服务第三方API(如supp

By Ne0inhk