给一个链表,若其中包含环,请找出该链表的环的入口节点,否则,输出null。
首先要声明两个指针p1
和p2
- 判断该链表中有没有环:
p1
和p2
从头开始出发,p1
每次移动一步,p2
每次移动二步,若是有环的话它们总会相遇; - 判断出有环存在后, 从环内的某个节点开始走, 查询出该环的长度
length
; p1
,p2
都回到头部,p1
先移动length
步, 然后同时移动,当p1
等于p2
的时候即为环的入口节点.
/*
* 查找出链表中环的入口节点
* params {ListNode} list
* returns {ListNode}
*/
function entryNodeOfLoop(list) {
if (!list || !list.next) return null
// 1.判断链表中是否有环
let p1 = list.next,
p2 = list.next.next
while (p1 != p2) {
if (p2 === null || p2.next === null) return null
p1 = p1.next
p2 = p2.next.next
}
// 2.获取环的长度
let temp = p1
let length = 1
p1 = p1.next
while (temp != p1) {
p1 = p1.next
length++
}
// 3.查询入口节点
p1 = p2 = list
while (length-- > 0) {
p1 = p1.next
}
while (p1 != p2) {
p1 = p1.next
p2 = p2.next
}
return p1
}