给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
3->2->0->-4
|______|
示例 2:
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
1->2
|__|
示例 3:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。
1
进阶: 你是否可以不用额外空间解决此题?
Java代码:
public class Solution {
/**
* 1--2--3--4
* |_____|
*
* 初始时:slow、fast指向head
* slow慢指针每次移动一步、fast快指针每次移动两步,相遇时,假设slow指针移动了x步,fast指针移动了2x步
* slow和fast指针在节点4相遇
*
* 假设head到环的入口(即节点2)的长度为a,slow指针在环内走的长度为b,环的长度为c,
* a+b = x
* a+b+c = 2x
* => c = x即环的长度
* slow指针走了环的长度,需找到环的入口(即节点2),只需用一个工作指针p,从head出发,slow指针同时移动
* slow与p相遇处,即为环的入口
* (相遇时,p走了a步,slow走了x+a步,x为环的长度,因此p与slow会相遇)
*
*/
public ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head, p = head;
while (null != fast && null != fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
break;
}
if (null == fast || null == fast.next)
return null;
while (p != slow) {
slow = slow.next;
p = p.next;
}
return p;
}
}