题目描述:
一个链表中包含环,请找出该链表的环的入口结点。
思路:
1、判断链表是否存在环,若存在求出环中节点数目nodesInLoop
- 求环中节点数目,首先要先进入环,定义两个指针,一个一次沿链表走两个节点,一个一次走一个节点,两个指针相遇的节点肯定在环中,然后从相遇节点开始沿链表走,再次回到该节点所用步数,即为环中节点个数。
2、定义两个指针,一个先沿链表走nodesInLoop步,剩余节点个数就等于链表中环入口节点之前的节点个数,两个指针同时沿链表移动,指针相遇的节点,即为链表中环的入口节点(此时先走的指针绕环一周,回到环入口节点)
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead){
ListNode* meetingNode = MeetingNode(pHead);
if (meetingNode == nullptr) return nullptr;
int nodesInLoop = 1;
ListNode* pNode1 = meetingNode;
//求出环中节点个数
while (pNode1->next != meetingNode) {
pNode1 = pNode1->next;
++nodesInLoop;
}
pNode1 = pHead;
//一指针先走nodesInLoop步
for (int i = 0; i <nodesInLoop; ++i)
pNode1 = pNode1->next;
ListNode* pNode2 = pHead;
while (pNode1 != pNode2) {
pNode1 = pNode1->next;
pNode2 = pNode2->next;
}
return pNode1;
}
//求出环中一节点
ListNode* MeetingNode(ListNode* pHead) {
if (pHead == nullptr) return nullptr;
ListNode* pSlow = pHead->next;
if (pSlow == nullptr) return nullptr;
ListNode* pFast = pSlow->next;
while (pFast != nullptr && pSlow != nullptr) {
if (pFast == pSlow)
return pFast;
pSlow = pSlow->next;
pFast = pFast->next;
if (pFast != nullptr)
pFast = pFast->next;
}
return nullptr;
}
};