带你透彻理解寻找环形链表全过程

278 阅读2分钟

网上很多关于环形链表的算法,但是相信不是每一个人都可以透彻理解。我在这里为大家推演一下,相信理解了下面的推演过程,我可以保证你对于找环形链表的算法再也不惧怕,牢记于心中,以不变应万变

废话少说先上代码:

import java.util.*;

class Program {
  public static LinkedList findLoop(LinkedList head) {
    LinkedList slow = head.next;
    LinkedList fast = head.next.next;

    while(slow != fast){
        slow = slow.next;
        fast = fast.next.next;
    }
    // slow和fast值相同,说明在环形链表中相遇,此时把fast指针移动到head节点。
    fast = head;
    while(slow != fast){
        fast = fast.next;
        slow = slow.next;
    }
    return fast;
  }

  static class LinkedList {
    int value;
    LinkedList next = null;

    public LinkedList(int value) {
      this.value = value;
    }
  }
}

代码很简单,但是想要知道为什么第二个while循环结束就能得到环形链表开始的地方,且听我娓娓道来,一定要仔细的看图,跟上我的文字思路: image.png

图中的几个变量说明:

  • D变量代表的是head节点 -> 环形节点开始的地方。
  • P变量代表的是slow节点和fast节点相遇时,slow在环形链表中的步长。
  • R变量代表的是slow节点还有多少步长就到达环形链表开始的地方。
  • T变量代表的是链表的总长度。

通过图中变量目前可以得到T = D + R + P的结论,但是目前好像还无法解开这道题,最关键的就是R变量了,如何让slow节点走完R变量停下,得到环开始的位置呢?让我们继续推演!!!

已知slow的步长是1,fast节点的步长是2,假设slow = x,那么fast = 2x

已知slow节点走过的步长是 D + P,所以slow = X = D + Pfast = 2X = 2D + 2P

fast节点比slow节点多走了一个P的距离,因此继续得出T = 2D + P

现在有两个对于T变量的结论,T = D + R + PT = 2D + P

把P变量去掉,得出D + R = 2D,也就是D + R = D + D,继续去掉一个D变量,得出D = R。也就是两个指针,一个走完D的距离,另一个也必定能走完R的距离,而R距离走完后停下,必定是环开始的地方。


所以才会把fast指针移动到head处,fast和slow指针都以步长为1的方式走,fast走的是D的距离,而slow走的是R的距离,因此当他们全部走完,值相同时,就是环开始的地方。

完结撒花🎉,有小伙伴不懂的地方可以一起讨论哦,大家一起成长一起进步。