题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路
(1)判断是否有环存在
设置快慢指针,快指针一次走2步,慢指针一次走1步;当快指针=null时说明没有环存在;如果有环存在,则必然有快指针追上慢指针
(2)当快指针追上慢指针后,此时必然位于环之内。然后通过再走一圈环,得到环的长度r
(3)类似题目“链表倒数第k个节点”,通过设计两个指针来遍历。前一个指针先走r步,然后后一个指针开始走。两个指针同时走,当两个指针相同时,说明时环的入口节点。
代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
// 设置快慢指针,如果快指针赶上慢指针,说明有环
// 快指针每次走2步;慢指针每次走1步
if(pHead== nullptr)
return nullptr;
ListNode* fast = pHead->next;
ListNode* slow = pHead;
while(fast!=nullptr && fast!= slow){
fast = fast->next;
if (fast!=nullptr)
fast = fast->next;
slow = slow->next;
}
if (fast==nullptr)
return nullptr;
// 计算环的长度
int loopLen = 1;
ListNode *lastFast = fast;
fast = fast->next;
while(fast!=lastFast){
fast = fast->next;
++loopLen;
}
fast = pHead;
slow = pHead;
// 让快指针先走loopLen步,慢指针再开始走
for(int i =0;i<loopLen; ++i){
fast = fast->next;
}
while(fast!=slow){
fast = fast->next;
slow = slow->next;
}
return fast;
}
};