问题描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
C++代码实现
思路:1、set集合,循环遍历,没有则插入,有的输出,直到遍历结束
2、使用双指针
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
#include<unordered_set>
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
unordered_set<ListNode*>st;
while(pHead)
{
if (st.find(pHead) == st.end())
{
st.insert(pHead);
pHead = pHead->next;
}
else
{
return pHead;
}
}
return NULL;
}
};
1、快慢指针,初始化fast
,slow
指针指向首结点
2、fast
走两步,slow
走一步,直到相遇
3、fast
指向首结点,slow
原地不动,两指针各走一步,直到相遇
1、slow
首次走到B点时,第一次相遇点在C
点,fast
走到F
点,设AB = x,BC = y
2、slow
从B->C
,fast
从F->B->C
,slow
走过y
距离,fast
走过2y
距离,所以FB+BC=2y
,即FB = y
3、第一次相遇在C
点,slow
走过A->B->C
,x+y
。fast
走过A->B->C->D->F->B->C
,2x+2y
。
4、AB+BC = x+y,AB+BC+CD+DF+FB+BC = 2x+2y,即CD+DF = x-y
5、此时fast
指向首部,slow
在相遇点C
点,开始每个指针走一步
6、fast
走到环形入口,AB = x
。slow
走到环形入口,CD+DF+FB = x-y+y = x
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode* fast = pHead;
ListNode* slow = pHead;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
break;
}
}
if (!fast || !fast->next)
{
return nullptr;
}
fast = pHead;
while(fast != slow)
{
fast = fast->next;
slow = slow->next;
}
return fast;
}
};