【剑指offer刷题】-23-链表中环的入口节点

题目描述:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

注:常考题目,快慢指针的应用

思路:分两步:

第一步:确定链表是否有环。定义快慢指针:pFast,pSlow;pFast每次走两步,pSlow每次走一步,进行遍历,如果两个指针相遇,即pFast=pSlow,则链表有环,如果pFast达到链表尾部(pFast->next=nullptr)两个指针都没有相遇,则链表没有环。

第二步:找到环的入口。首先确定环中节点的个数n,从第一步快慢指针相遇的节点出发,一边继续向前移动一边计数,当再次回到这个节点时,就可以得到环中节点个数n。然后定义连个指针p1,p2,p1先向前移动n步,p1和p2以相同的速度想想移动,当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==nullptr) return nullptr;
        ListNode *pFast=pHead,*pSlow=pHead->next;
        //判断是否有环
        while(pFast!=nullptr&&pSlow!=nullptr&&pFast!=pSlow){
            pSlow=pSlow->next;
            pFast=pFast->next;
            if(pFast!=nullptr)
                pFast=pFast->next;
        }
        //统计环中的节点数
        int cntNum=1;
        ListNode *pTemp=pFast->next;
        
        if(pSlow==pFast&&pFast!=nullptr){
            while(pTemp!=pFast){
               pTemp=pTemp->next;
               ++cntNum;
            }

        }
        else
            return nullptr;

        //寻找链表的入口结点
        ListNode *pNode1=pHead,*pNode2=pHead;
        for(int i=0;i<cntNum;++i){
            pNode1=pNode1->next;
        }
        while(pNode2!=pNode1){
            pNode2=pNode2->next;
            pNode1=pNode1->next;
        }
        return pNode1;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值