题目描述:
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出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;
}
//下面这两句一定要注意,之前写的代码给fast和slow这两个指针都赋的是pHead,这导致while(fast!=slow)直接就符合要去,这样不行
//要在初始化的时候给fast和slow赋两步和一步的初值,才能在下面的while循环中相遇与一点
ListNode *fast=pHead->next->next;
ListNode *slow=pHead->next;
ListNode *temp=pHead;
while(fast!=slow)
{
//代码的鲁棒性,链表中未必有环,没有环的话直接就返回NULL
if(fast->next!=NULL&&fast->next->next!=NULL)
{
fast=fast->next->next;
slow=slow->next;
}
else
{
return NULL;
}
}
ListNode *meet=fast;
//从头结点和相遇结点开始出发,会会和在环的入口结点
while(meet!=temp)
{
meet=meet->next;
temp=temp->next;
}
return meet;
}
};