题目:
//给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
思路:
快慢指针,快指针每次前进两个长度,慢指针每次前进一个长度,若存在环,则一定会在环内相遇。
假设起点到环入口长度a,环入口到相遇点长度为b,相遇点到环入口长度为c,环长度为r,则有如下关系:
2(a+b) = a+b+nr
a+b = nr
a+r-c = nr
a = c+(n-1)r
所以当存在环时,令两个指针分别从相遇点和头出发,相遇点即为环入口
代码:
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(NULL == pHead || NULL == pHead->next)
{
return NULL;
}
ListNode * slow = pHead;
ListNode * fast = pHead;
while(NULL != fast && NULL != fast->next)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
return GetEntryNodeOfLoop(fast, pHead);
}
}
return NULL;
}
ListNode* GetEntryNodeOfLoop(ListNode* fast, ListNode* pHead)
{
while(fast != pHead)
{
fast = fast->next;
pHead = pHead->next;
}
return fast;
}
};