给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。
进阶:
你是否可以不用额外空间解决此题?
思路图解:
代码实现:
/**
* 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) {
//慢行指针slow
ListNode slow = head;
//快行指针fast
ListNode fast = head;
//在一个环上,看做谁追谁不是绝对的
while (true) {
//若没有环,fast的最终指向会为空
if (fast == null || fast.next == null) {
//无环直接返回空
return null;
}
//慢行指针步进1
slow = slow.next;
//快行指针步进2
fast = fast.next.next;
//相遇则暂停
if (slow == fast) {
break;
}
}
//p即为图解中指向原点O的指针
//图解中指向P的指针还是slow
ListNode p = head;
while (p != slow) {
//两者步进都为1走向图解中的A点
p = p.next;
slow = slow.next;
}
//循环退出时即同时到达A点
//返回图解A处的结点即为答案
return p;
}
}