欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LeetCode刷题--环形链表(二)

程序员文章站 2022-05-29 09:28:39
...

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

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

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

/**
 * 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) {
      //先对链表进行一个自检
      if(head == null || head.next == null){
          return null;
      }
      //定义一个快指针,慢指针,判断有无环
      //快指针每次走两步,慢指针每次走一步
      //设在环状列表入口前有a个节点,环形里面有b个节点,链表总共有a+b个节点
      //那么在相遇时,fast指针走了s+nb步
      //fast是slow的步数两倍,所以f = s+nb = 2s
      //f = 2nb, s= nb,这是第一次相遇时两个指针走的步数
      //此时我们想知道环形的入口,s已经走了nb步,我们只要再让s走a步数停下来,
      //把这个链表的环状走完,他(s)就从链表口,也就是环形入口那里出来了
      //就可以知道链表环状入口在哪里了
      //依旧使用双指针的方法,我们定义一个指针,从头开始走,陪着s走a步,在环状入口他们就会第二次相遇
      //因为他们一起把链表走完了
      ListNode fast = head;
      ListNode slow =head;
      while(true){
          if(fast.next == null || fast.next.next == null){
           return null;
          }
          fast = fast.next.next;
          slow = slow.next;
          if(fast == slow){break;}
      }
      fast = head;
       while(fast != slow){
           fast = fast.next;
           slow = slow.next;
       }
       return fast;
}
}

我的理解就是:第一次相遇只是为了让slow指针放在nb步数的位置上,第二次相遇的fast指针,为了助于理解,可以用其他的变量名称来代替,它是陪着slow走了a步,构造第二次相遇。
为了更好说明,下面附上几张比较重要的图,
LeetCode刷题--环形链表(二)
LeetCode刷题--环形链表(二)
LeetCode刷题--环形链表(二)
LeetCode刷题--环形链表(二)

相关标签: 随笔