《剑指Offer》学习笔记--面试题56:链表中环的入口结点

来源:互联网 发布:25转行做程序员 编辑:程序博客网 时间:2024/05/14 01:58

题目:一个链表中包含环,如何找出环的入口结点?

可以用两个指针来解决这个问题。先定义两个指针P1和P2指向链表的头结点。如果链表中环有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。

剩下的问题就是如何得到环中结点的数目。我们在面试题15的第二个相关题目时用到了一快一慢的两个指针。如果两个指针相遇,表明链表中存在环。两个指针相遇的结点一定是在环中。可以从这个结点出发,一边继续向前移动一边计数,当再次回到这个结点时就可以得到环中结点数了。

下面代码中函数MeetingNode在链表中存在环的前提下找到一快一慢两个指针相遇的结点:

ListNode* MeetingNode(ListNode* pHead){if(pHead == NULL)return NULL;ListNode* pSlow = pHead->m_pNext;if(pSlow == NULL)return NULL;ListNode* pFast = pSlow->m_pNext;while(pFast != NULL && pSlow != NULL){if(pFast == pSlow)return pFast;pSlow = pSlow->m_pNext;pFast = pFast->m_pNext;if(pFast != NULL)pFast = pFast->m_pNext;}return NULL;}

如果链表中不存在环,那么函数MeetingNode返回NULL。

在找到环中任意一个结点之后,就能得出环中的结点数目,并找到环的入口点。相应的代码如下:

ListNode* EntryNodeOfLoop(ListNode* pHead){ListNode* meetingNode = MeetingNode(pHead);if(meetingNode == NULL)return NULL;//get the number of nodes in loopint nodesInLoop = 1;ListNode* pNode1 = meetingNode;while(pNode1->m_pNext != meetingNode){pNode1 = pNode->m_pNext;++ nodeInLoop;}//mode pNode1pNode1 = pHead; for(int i = 0; i < nodesInLoop; ++ i)pNode1 = pNode1->m_pNext;//move pNode1 and pNode2ListNode* pNode2 = pHead;while(pNode1 != pNode2){pNode1 = pNode1->m_pNext;pNode2 = pNode2->m_pNext;}return pNode1;}


0 0
原创粉丝点击