[路飞]_环形链表

134 阅读1分钟

1. 找出环形链表起始点

给定一个链表,判断链表中是否有环。如果有环,请找出起始点

image.png

1.1 借助哈希表

解题思路:

  • 哈希表存遍历过的节点,每遍历一个节点,都查看哈希表是否存在当前节点,如果存在,则说明链表有环
  • 如果不存在,则存入哈希表,继续遍历

代码实现如下:

var hasCycle = (head) => { 
    let map = new Map(); 
    while (head) { 
        if (map.has(head)) return head; 
        map.set(head, true); // 存的是节点的地址引用,而不是节点值 
        head = head.next; 
    } 
    return false; 
};



1.2 快慢指针法

解题思路:

image.png

p为慢跑者,当p跑至起始点时,快跑者q经过距离为2a,设定q点距离起始点x,由于q速度是p的2倍,由此可以得出当q需要再经过2x的距离才能追上p,此时慢跑者经过距离为x即起始点到交汇处距离为x,由此可以得出交汇处到起始点距离与head到起始点距离相同,此时只需新人r从起始点以p的速度同时开跑,当r与p相遇时,即为环形的起始点

代码实现如下:

var detectCycle = function(head) {
    if(!head) return null
     var pre = head,cur = head
     while(cur && cur.next) {
          pre = pre.next
          cur = cur.next.next
          if(pre === cur) { //判断是否有环
              var temp = head  //此为新人r
              while (pre != temp) { //判断新人r与p是否交汇
                  temp = temp.next
                  pre = pre.next
              }
              return temp
          }
     }
     return null
};