連結串列中環的入口節點——NC.3
阿新 • • 發佈:2021-01-18
題目描述
對於一個給定的連結串列,返回環的入口節點,如果沒有環,返回null 拓展: 你能給出不利用額外空間的解法麼?
解題分兩個步驟:
- 首先,用快慢指標判斷是否有環,有的話,返回相遇時節點
- 兩個指標分別從head和相遇的節點開始遍歷,再次相遇時就是環的入口處節點
有一個證明過程:
假設在Z處相遇,根據快指標是慢指標的速度兩倍,可得出:
a
+
b
+
n
(
b
+
c
)
=
2
∗
(
a
+
b
)
a + b + n (b + c) = 2 * (a + b)
a+b+n(b+c)=2∗(a+b)
即:
a
=
(
n
−
1
)
∗
(
b
+
c
)
+
c
a = (n - 1) * (b + c) + c
a=(n−1)∗(b+c)+c
也就是說,若將兩指標分別放在起始位置和相遇位置,並以相同速度前進,當一個指標走完距離a時,另一個指標恰好走出 繞環n-1圈加上c的距離。
/**
* 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) {
ListNode meetNode = checkCycle(head);
if (meetNode == null) {
return null;
}
ListNode slow = meetNode;
ListNode fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast. next;
}
return slow;
}
public ListNode checkCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
return fast;
}
}
return null;
}
}