给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 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; } }