一个链表中包含环,请找出该链表的环的入口结点

问题分析:设置两个指针,pSlow初始化为pHead,在后,走的慢;pFast初始化为pHead->next,在前,走的快,二者一定会在环内相遇;二者相遇之后设置计数器,令指针沿着环走一圈,计算环中元素数量;设置两个指针p1和p2,令p1先走环中元素数量的位置,然后两个同时走,二者会在环入口相遇

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
       if(pHead==NULL)return NULL;
         //先计算环中结点的个数
         //快慢指针相遇结点一定在环中
        //每向前走一步,检验是否为空,避免链表不是环的时候,程序出错
         ListNode *pSlow=pHead,*pFast=pHead->next;
         while(pFast!=NULL&&pSlow!=NULL)
         {
            pSlow=pSlow->next;
            pFast=pFast->next;
            if(pFast==pSlow) break;
            if(pFast!=NULL)
                pFast=pFast->next;
         }
         //开始统计环结点数
         int countNum=1;
         ListNode *pTempNode=pFast->next;
         if(pFast==pSlow&&pFast!=NULL)
         {
             while(pTempNode!=pFast)
             {
                 pTempNode=pTempNode->next;
                 ++countNum;
             }
         }
         else
             return NULL;
         //再设两指针,一先一后
         ListNode *p1=pHead,*p2=pHead;
         for(int i=0;i<countNum;i++)
                p1=p1->next;
         while(p1!=p2)
         {
             p1=p1->next;
             p2=p2->next;
         }
         return p1;
    }
};

这段代码的第一个循环,寻找快慢指针的相遇点,while条件中没有给出循环终止条件pSlow!=pFast,当找到这个点的时候,用break结束循环。这里也可以将这个循环终止条件

         ListNode *pSlow=pHead,*pFast=pHead->next;
         while(pFast!=NULL&&pSlow!=NULL&&pFast!=pSlow)
         {
            pSlow=pSlow->next;
            pFast=pFast->next;
            if(pFast!=NULL)
                pFast=pFast->next;
         }
注意:为了防止非正常数据,如输入的指针不是环,最好每走一步,检验指针是否为空

猜你喜欢

转载自blog.csdn.net/happyjacob/article/details/80671584