题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
解题思路:
使用快慢指针,慢指针p1一次走1步,快指针一次走2步,首先如果有环,那么必定会在环中某个位置相遇,且此时快指针比慢指针多走了一个环的距离。
我们假设从头节点到入口节点的距离是a,从入口节点到相遇点的距离为b,从相遇点到入口的距离为c,环中顺时针走。那么a+(b+c)k+b是相遇点时快指针p2走的距离,其中k表示走的圈数且k>=1,a+b是相遇点时慢指针p1走的距离,2*(a+b) = a+(b+c)*k+b,简化得到a=(k-1)(b+c)+c,意义是从头节点到入口点的距离=从相遇点到入口点的距离+(k-1)圈,k大于等于1,则表示从头结点向后走必定与相遇点顺时针走在入口节点相遇。
class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { ListNode *p1 , *p2; p1 = pHead; p2 = pHead; //找到环中第一次相遇的节点 while(p1 != NULL && p2!= NULL){ p1 = p1->next; p2 = p2->next; if(p2 == NULL){ break; }else{ p2 = p2->next; } if(p1 == p2){ break; } } //无环 if(p1 == NULL || p2 == NULL){ return NULL; } p2 = pHead; //再次相遇的地方就是入口节点 while(p2 != p1){ p1 = p1->next; p2 = p2->next; } return p1; } };