142.环形链表 II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

思路:

  • 先判断是否有环,如果无环,则直接返回 null;
  • 如果有环,分析:
    ○ 头结点到环开始的节点,设有 a 步,环有 b 步;
    ○ 则:slow = s , fast = 2*s(快指针每次走 2 步,路程刚好是 慢指针的 2 倍);
    ○ fast = s + n*b(相遇时,快指针比慢指针多走 n 圈, n 未知);
    ○ 推出==> : s = n*b
    ○ 从 head 节点到入环点要走:a + n*b(n = 0,1,2,3…,理解不了就当 n = 0);
    ○ 而 slow 已经走了 nb 步,那么 slow 再走 a 步,就是入环点了;
    ○ 如何走 a 步?从 head开始,和 slow 一起走,相遇时就刚好就是走了 a 步

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head == null) return null;
        ListNode slow = head, fast = head; // fast = head,不能让他先走一步
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast) break; //有环
        }
        if(fast == null || fast.next == null) return null;//无环,返回结束
        while(head != slow){
            slow = slow.next; //slow 和 head 开始走 a 步
            head = head.next;
        }
        return slow;
    }
}
原文地址:https://www.cnblogs.com/luo-c/p/13849086.html