链表中环的入口结点
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
解题思路
链表中,用快慢两指针,
- 首先确定是否链表中有环
- 如果快指针先到了链表的结尾,则肯定没有环
- 否则,快慢指针一定会相遇
- 然后慢指针置头结点,一步一步走,两个指针再次相遇的节点,即为链表中的环的入口
- 当fast == slow时,假设slow走过x个节点,则fast走过2x个节点。设环中有n个节点,因为fast比slow多走一圈(n个节点),所以有等式2x = n + x,可以推出n = x,即slow实际上走了一个环的步数。这时,我们让fast重新指向链表头部pHead,slow的位置不变,然后slow和fast一起向前每次走一步,直到fast == slow,此时两个指针相遇的节点就是环的入口。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
bool isHaveLoop = false;
ListNode* fast = pHead;
ListNode* slow = pHead;
if(fast == NULL || fast -> next == NULL || fast -> next -> next == NULL){
return NULL;
}
while(fast -> next -> next != NULL){
fast = fast -> next -> next;
slow = slow -> next;
if(fast == slow){
isHaveLoop = true;
break;
}
}
if(isHaveLoop){
slow = pHead;
while(slow != fast){
slow = slow -> next;
fast = fast -> next;
}
return slow;
}
return NULL;;
}
};