二叉树之下

手撕代码 之 环形链表

2018-05-26  本文已影响36人  孙树冲

1. 环形链表的判定

2. 环形链表的环入口

  • 慢指针走的距离: a + x
  • 快指针走的距离: a + x + n*r (n为快指针多走的圈数)
  • 由于慢指针每走一步,快指针走两步,故有: 2 * (a + x) = a + x + n * r
    所以: a + x = n * r
  • 我们对这个式子进行转换一下, 有: a = (r-x) + (n-1) * r

那么,这个式子说明了什么呢?很明显,等号左侧是从链表起点到入环节点的距离;对于等号右边,前一项(r-x) 表示的是从快慢指针相遇的位置到下一次来到入环节点的距离,后一项表示若干个环的距离。由此我们就得到了这个问题的答案:

当快慢指针相遇时,我们使用两个指针分别指向链表的头节点和相遇节点,然后二者同时移动,每次移动一步,那么下一次二者相遇的节点就是入环节点。

class Node{
  int val;
  Node next;
}

public boolean cyclicEntrance(Node head){
  if(head==null)  return null;
  Node fast = head, slow = head;
  Node p2 = null;
  while(slow != null && fast!=null && fast.next != null){
    fast = fast.next.next;
    slow = slow.next;
    if(slow == fast){
      p2 = slow;
      break;
    }
  } 
  Node p1 = head;
  while(p1 !=null && p2 != null){
    if(p1 == p2)  return p1;
    p1 = p1.next;
    p2 = p2.next;
  }
}  

3. 求解环上的节点数目

4. 两个链表是否相交(拓展题)

上一篇下一篇

猜你喜欢

热点阅读