您的位置:首页 > 职场人生

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

2015-05-17 13:11 656 查看
题目:一个链表中包含环,如何找出环的入口结点?

可以用两个指针来解决这个问题。先定义两个指针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 loop
int nodesInLoop = 1;
ListNode* pNode1 = meetingNode;
while(pNode1->m_pNext != meetingNode){
pNode1 = pNode->m_pNext;
++ nodeInLoop;
}

//mode pNode1
pNode1 = pHead;
for(int i = 0; i < nodesInLoop; ++ i)
pNode1 = pNode1->m_pNext;

//move pNode1 and pNode2
ListNode* pNode2 = pHead;
while(pNode1 != pNode2){
pNode1 = pNode1->m_pNext;
pNode2 = pNode2->m_pNext;
}

return pNode1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: