1. 找出环形链表起始点
给定一个链表,判断链表中是否有环。如果有环,请找出起始点
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 快慢指针法
解题思路:
-
追及问题延伸
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
};