题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
此处借助leetcode上大佬的作图以便大家理解,该图的原地址在下文中已给出。
一、解题思路
使用双指针,一个快指针 fast 每次移动两个节点,一个慢指针 slow 每次移动一个节点。因为存在环,所以两个指针必定相遇在环中的某个节点上。(就好像运动会5000米跑圈,大家虽然一个起点,但是跑的慢的人会被跑的最快的那个人套圈)
至于怎样找到入口节点的证明建议大家参考我给出的两个链接,一个是图文(戳我),一个是视频(戳我),非常详细,我就不在此处赘述了。参考这两个对大家的理解必有裨益。另外推荐前端的小伙伴关注视频连接里的那个叫JS老毕的up,宝藏啊。想用js刷l算法的你会收获一份惊喜。
二、直接上参考代码
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function EntryNodeOfLoop(pHead)
{
// write code here
if(!pHead || !pHead.next){
return null;
} // 没有节点或者只有一个节点的情况
let fast = pHead;
let slow = pHead;
while(fast) {
fast = fast.next.next; // fast指针每次走两步;
slow = slow.next // slow 指针每次走一步;
if (fast === slow) {
break; // 找到首次相遇节点,退出循环
}
}
if (!fast) {
return null; // 不存在环
}
fast = pHead; // 重新指向第一个节点
while(true) {
if (fast == slow) {
return slow;// 找到环入口节点
}
fast = fast.next // 每次只走一步
slow = slow.next // 每次只有一步
}
return null;
}
总结
以上就是今天要讲的内容,理解原理后代码实现起来并不复杂,但是实现的思路确实需要好好研究的,本文仅仅作为本人的学习记录欢迎大家积极交流。