題目
題目鏈接
給定一個有環鏈表,實現一個算法返回環路的開頭節點。
有環鏈表的定義:在鏈表中某個節點的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;
}
}