您的位置:首页 > 其它

链表中环的入口节点

2019-06-12 15:02 218 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/zb_915574747/article/details/91524246

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

一个带环的链表,设置两个快慢指针,两指针速度不同,一定会在环中相遇(类似在环形操场跑步,跑的快的的终究会追上跑的慢的,可能跑了好几圈才追上),两指针相遇时,快指针跑了n圈环ny+非环路程x+环入口到相遇点路程a(s_fast=x+ny+a),慢指针跑了m圈环my+非环路程x+环入口到相遇点路程a(s_slow=x+my+a),设v_fast=2v_slow,则2s_fast=s_slow,即2(s_fast=x+ny+a)=s_slow=x+my+a,求解x=(n- 2 *m -1 )*y + y- a,即非环路程x=整个环路程*s(s=0,1,...)+(整个环路程-环入口到相遇点路程),可将整个环路程*s忽略,得到x=y-a(整个环路程-环入口到相遇点路程)。

所以可以先让快慢指针同时跑,一定会在环中相遇,然后将快指针重新置为原点,此时将两指针速度调为一致,当两指针相遇时,相遇点即为环的入口。

代码

[code]/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==nullptr||pHead->next==nullptr)
{
return nullptr;
}
ListNode *fast=pHead->next->next;
ListNode *slow=pHead->next;
while(fast!=slow)
{
if(fast->next->next!=nullptr&&fast->next!=nullptr)   //判断是否有环
{
slow=slow->next;
fast=fast->next->next;
}
else
return nullptr;         //没有环,直接返回nullptr
}
fast=pHead;
while(fast!=slow)
{
fast=fast->next;
slow=slow->next;
}
return slow;
}
};

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: