1. 程式人生 > 其它 >連結串列中環的入口節點——NC.3

連結串列中環的入口節點——NC.3

技術標籤:牛客題霸演算法篇快慢指標連結串列

題目描述

對於一個給定的連結串列,返回環的入口節點,如果沒有環,返回null 拓展: 你能給出不利用額外空間的解法麼?

解題分兩個步驟:

  1. 首先,用快慢指標判斷是否有環,有的話,返回相遇時節點
  2. 兩個指標分別從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=(n1)(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; } }