剑指offer题型分类及各题的代码及解题思路
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
链表结点定义如下:
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
思路:(剑指offer第二版 P139)
两个指针一个fast、一个slow同时从一个链表的头部出发,
fast一次走2步,slow一次走一步,如果该链表有环,两个指针必然在环内相遇,
此时只需要把其中的一个指针重新指向链表头部,另一个不变(还在环内),
这次两个指针一次走一步,相遇的地方就是入口节点。
C++实现代码如下:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode* fast = pHead;
ListNode* slow = pHead;
//1、若有环,fast一次走一步,slow一次走两步,找到两个指针相遇的结点
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
break;
}
//2、说明无环,直接返回NULL
if(fast == NULL || fast->next == NULL)
return NULL;
//3、从相遇结点开始,让fast重新指向头结点,然后两个指针同步往后移动,再次相遇的结点即为环的入口结点
fast = pHead;
while(fast != slow)
{
fast = fast->next;
slow = slow->next;
}
return fast;
}