题目
题目链接
给定一个有环链表,实现一个算法返回环路的开头节点。
有环链表的定义:在链表中某个节点的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
解释:链表中没有环。
实现思路
利用快慢指针求解。
慢指针每次走一步,快指针每次走两步,在快慢指针都不为null时,如果快慢指针相遇,则一定有环,否则没环,确定相遇位置。
慢指针原地不动,快指针回到起点,快慢指针同时出发一次一步,知道快慢指针再次相遇,相遇的节点就是环的入口。
细节如图所示:
代码如下
/**
* 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 fast = head;
ListNode low = head;
//判断是否为环 走完此循环若fast等于low则一定有环
while (fast != null && low != null) {
if (fast.next == null) {
return null;
}
fast = fast.next.next;
low = low.next;
if (low == fast) {
break;
}
}
System.out.println(low.val);
System.out.println(fast.val);
//两者不相等说明没有环
if (fast != low) return null;
fast = head;
//low待在原地 fast会原点 快慢指针每次都走一步直到找到相遇的位置 就是环的入口
while (fast != low) {
fast = fast.next;
low = low.next;
}
return low;
}
}