链表中环的问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/isluckyguo/article/details/84278423

问题:如果一个链表中包含环,如何找出环的入口节点?如下图链表中,环的入口节点是节点3.

解题思路:第一步是如何确定一个链表中是否包含一个环,也可以采用两个指针来解决,定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步,如果走的快的指针追上了走的慢的指针,那么链表中就包含环,如果走的快的指针走到链表末尾了(m_pNext==nullptr)都没追上走的慢的指针,那么链表中就不存在环。第二步是要确定环的入口,同样利用两个指针,先定义两个指针P1,P2指向链表头节点,如果链表中的环有n个节点,则指针P1先在链表上向前移动n步,然后两个指针以相同的速度向前移动,当第二个指针指向环的入口节点时,第一个指针已经围绕环走了一圈,又回到了入口节点。 那么如何得到环中节点的数目,前面判断链表中是否有环用到两个指针,如果两个指针相遇则说明链表中有环,而且两个指针相遇的节点一定是在环中,那么从这个节点出发,一边继续向前移动一边计数,当再次回到这个节点时,就可以得到环中节点数了。

ListNode *MeetingNode(ListNode *pHead)
{
    if(pHead == nullptr)
        return nullptr;

    ListNode *pSlow = pHead->m_pNext;
    if(pSlow == nullptr)
        return nullptr;

    ListNode *pFast = pSlow->m_pNext;
    while(pFast != nullptr && pSlow != nullptr)
    {
        if(pFast == pSlow)
            return pFast;

        pSlow = pSlow->m_pNext;
        
        pFast = pFast->m_pNext;
        if(pFast != nullptr)
            pFast = pFast->m_pNext;
    }

    return nullptr;
}

ListNode *EntryNodeOfLoop(ListNode *pHead)
{
    ListNode *meetingNode = MeetingNode(pHead);
    if(meetingNode == nullptr)
        return nullptr;

    int numNodeInLoop = 1;
    ListNode *pNode1 = meetingNode;
    while(pNode1->m_pNext != meetingNode)
    {
        pNode1 = pNode1->m_pNext;
        numNodeInLoop++;
    }

    pNode1 = pHead;
    for(int i=0; i<numNodeInLoop; i++)
        pNode1 = pNode1->m_pNext;

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

    return pNode1;
}

猜你喜欢

转载自blog.csdn.net/isluckyguo/article/details/84278423
今日推荐