题目:如果一个链表中包含环,找到环的入口结点,否则,输出null.
思路: ①明确链表是否包含环,通过两个指针–快指针和慢指针实现,快指针和慢指针同时从链表头结点出发,慢指针每次移动一个结点,快指针每次移动两个结点,若是快指针走到末尾时,慢仍未追上,则说明链表中不存在环,输出null;若是慢指针追上快指针,则说明链表包含环,且相遇的节点一定为环中某个结点。 ②找到环的入口结点,同样通过两个指针–前指针和尾指针来实现,初始位置都为头结点,令前指针先移动n个结点,其中n为环的组成结点数,接着前指针和尾指针同时同速移动,当前指针和尾指针相遇时,则说明该结点为环的入口结点。 因此解决该问题还需要先求解出环的结点数,在确定是否包含环时使用了快指针和慢指针,假设快指针和慢指针第一次相遇时,慢指针移动了x个结点,则快指针移动了2x个结点,快指针相对慢指针多移动了x个结点的位置,也就是环的结点数。
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; */ class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { if(pHead == nullptr) return nullptr; ListNode* pSlow = pHead; ListNode* pFast = pHead; while(pFast != nullptr && pFast->next != nullptr){ pSlow = pSlow->next; pFast = pFast->next->next; if(pSlow == pFast){ ListNode* pBefore = pHead; ListNode* pAfter = pSlow; while(pBefore != pAfter){ pBefore = pBefore->next; pAfter = pAfter->next; } if(pBefore == pAfter) return pAfter; } } return nullptr; } };