链表关键:头指针无前向指针,故引入dummy_head作为一定存在的头指针

如何获取位置?就像在操场跑步如何遇见彼此,有一定的差速即可

需处理结点前方的指针,故诞生慢指针,以作出操作,而快指针用于搜索

链表删除操作中,若找到待删结点的前一个结点,应该一直尝试围绕此结点删除,而不是删除后遍历至下一个结点

因为遍历至下一个节点时已经无法删除下一个结点,而下一个节点正好可能是需要删除的节点

/**
 * Definition for singly-linked list.
 * class ListNode {
 * int val;
 * ListNode next;
 * ListNode(int x) {
 * val = x;
 * next = null;
 * }
 * }
 * 为什么采用快慢指针而不是记录开头遍历?因为链表环路是局部的
 * 为什么当快指针只比慢指针移速快1的时候它们必定相遇?因为环的大小至少为1,不可能产生跳跃(快2、3时就可能出现溢出不相遇问题,比如如果环长为2,快指针快2
 * ,可能出现快慢指针相对不动)
 * n即圈差,快指针能追上慢指针是因为套圈了(>=1,刚好在慢指针进入时快指针转一圈则为快1圈,多出来的是因为快指针到时慢指针还没到,都在环内时,
 * 快指针追上慢指针因为差速为一至多环大小次,即多转一圈,或者说当慢指针要走到一圈时,快指针早快走完两圈,早已与它相遇)
 */
 
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast=head,slow=head,index1=head,index2;
        if(head==null) return null;
        //假设入口离头节点x,相遇时离入口y,差入口z,追圈时多走了n圈,fast走了n(y+z)+x+y,slow走了x+y,同时开始走,
        //则2(x+y)==n(y+z)+x+y,即x==z+(n-1)(x+y)==z(圈数被整除,无意义)
        while(fast.next!=null&&fast.next.next!=null)
        {
            fast=fast.next.next;
            slow=slow.next;
            if(slow==fast)
            {
                index1=fast;
                index2=head;
                while(index1!=index2)
                {
                    index1=index1.next;
                    index2=index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}