Leetcode 142题 环形链表 II(Linked List Cycle II) Java语言求解
题目描述:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
分析
给出示意图:
对符号的一些说明:
公式演算:
很容易得到:
m=x+y(环的长度两种表示形式);
快指针走两步,慢指针走一步。所以快指针的速度是慢指针的速度的二倍,所以相同时间内,快指针走的长度也是慢指针走的长度的二倍:
有: f=2s;
在快指针走过 圈后两指针相遇,有: m+kn+y=2(m+y);
去括号后有: m+kn=2m+y;
解得: m=kn-y;
又因为:n=x+y;
所以有:m=kn-(n-x);
所以:m=x+n(k-1)。
m是头节点到环起点的长度;
x是相遇点到头节点的长度;
x-m是(k-1)个环的长度。
通过公式的演算,我们能够明白:
找到相遇点后,链表头节点与相遇点节点同时出发,相遇处便是环的起点。相遇点节点多走了(k-1)个环。
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null)
return null;
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
break;
}
}
if(fast == null || fast.next == null)
return null;
fast = head;
while(slow != fast){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
对代码的解释:
1、如果head是空,则不存在环,直接返回null;
2、设置快慢指针开始均指向head,设置循环条件,快指针不为空且快指针的next域指向的不为空进入循环,其中空指针的next域的指向不为空保证快指针可以走两步,否则有可能出现空指针异常;
3、如果快慢指针指向相同节点,则break掉,是相遇点;
4、第一次循环过后,如果fast为空或者fast.next为空,则不存在环,返回null;
5、如果存在环,让fast指针从开始移动,slow指针从相遇点移动,相遇则为起点,将其return即可。
欢迎关注
扫下方二维码即可关注:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效