环形链表——双指针
原题在这里:
概述题意:
给定一个可能有环的链表,如果有环则返回第一个环节点,否则null
低配hash处理:

class Solution { map<ListNode *, int> mp; public: ListNode *detectCycle(ListNode *head) { if (!head || mp[head] == 1) return head; mp[head] = 1; return detectCycle(head->next); } };
高配双指针:
class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode *p = head, *q = head; while (p != nullptr) { q = q->next; if (p->next == nullptr) return nullptr; p = p->next->next; if (p == q) { //重新走一遍 p = head; while (p != q) { p = p->next; q = q->next; } return p; } } return nullptr; } };
analyse:
大概:
s快=s慢+n*b,s快=s慢*2,故得:s慢=n*b
如果有环,快指针与慢指针相遇时候,快指针一定比慢指针多走n倍环的长度b,又有快指针路径是慢指针两倍,所得慢指针当前路径为n倍环长度。
继续:
从此点开始,用两指针分别从头和快慢指针相遇节点开始走,相遇的节点即为入环节点。
也即s1=0,s2=n*b,那么走非环路径a后即有,s1=a,s2=a+n*b,两者相遇在入环节点。
code:
struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode *p = head, *q = head; while (p != nullptr) { q = q->next; if (p->next == nullptr) return nullptr; p = p->next->next; if (p == q) { //重新走一遍 p = head; while (p != q) { p = p->next; q = q->next; } return p; } } return nullptr; } };
【Over】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!