链表中环的入口节点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
方法1:用集合的方法
遍历链表,如果集合中没有这个节点,就放进集合,如果集合中有这个节点,就返回这个节点(该节点就是链表环的入口节点)
如果p为NULL了,证明该链表没有环,返回NULL
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
unordered_set<ListNode*> s;
ListNode* p=pHead;
while(1)
{
if(s.find(p)==s.end())
{
s.insert(p);
p=p->next;
}
else
return p;
if(p==NULL)
return NULL;
}
}
};方法2:快慢指针的方法
定义一个快指针,一个慢指针,快指针一次走两步,慢指针一次走一步;
如果快指针指向了NULL,则没有环;
若快慢指针相遇了,则证明一定有环;
此时,让快指针返回头结点,两个指针同时往前走,当两指针再次相遇时,该节点则为环的入口节点
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==NULL||pHead->next==NULL||pHead->next->next==NULL)
return NULL;
ListNode* pFast=pHead->next->next;
ListNode* pSlow=pHead->next;
while(pFast!=pSlow)
{
pFast=pFast->next->next;
pSlow=pSlow->next;
if(pFast->next==NULL||pFast->next==NULL)
return NULL;
}
pFast=pHead;
while(pFast!=pSlow)
{
pFast=pFast->next;
pSlow=pSlow->next;
}
return pFast;
}
};
