环形链表(二)
题目描述
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
题解(java)
public class Solution {
public ListNode detectCycle(ListNode head) {
//判断链表是否为空链表或只有一个节点
//=>是,没有环路,返回null
if (head == null || head.next == null) {
return null;
}
ListNode slow = head;
ListNode fast = head;
//如果fast == null 或 fast.next == null说明已经遍历到尾节点
//=>链表没有环路
while (fast != null && fast.next != null) {
//快指针的速度为慢指针的二倍
//快指针走过的路程也为慢指针的二倍
slow = slow.next;
fast = fast.next.next;
if (fast == slow) {
ListNode ptr = head;
//ptr 与 slow 在链表尾连接到链表中的位置相遇
while (ptr != slow) {
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
}
return null;
}
}
图示
详解
- 该题与环形链表(一)不同的是结果需要返回尾节点连接的节点,所以要运用到数学问题。
- 定义两个指针:fast(快指针),slow(慢指针),两指针在同一起点出发,fast的速度为slow的二倍,所以fast的路程也为slow的二倍,如上图,得到 a = (n-1)b+nc
- 再定义一个指针ptr,如上图slow从图中P的位置出发,ptr从头结点出发,最后两指针会在交点相遇,这时返回ptr的位置,为所求结果
Tips
-
注意:环(一)中给定两指针的初始位置为一前一后,这是因为slow = fast为遍历的终止条件,且所求结果只是要求判断是否为环形链表所以不对两指针的初始位置有严格要求;
而环(二)中只有当两指针的初始位置相同,且速度为二倍关系时,才能得到最后恰好在连接处相遇的等式,否则因为ptr与slow的速度相同,所以如果在连接点处不能相遇,则会在环路中永不相遇,陷入死循环。 -
注意:因此遍历终止条件也有所改变
难点
数学问题
声明
- 原作者:E.L.E
- <商业用途转载请获得原作者允许,非商业用途转载请注明来处>
- <欢迎大家评论>