面试题(二十三) 链表中环的入口节点

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

思路:关键是要想到:如果链表存在环,则设置一快一慢两个指针同时从链表头出发,那么快的指针必定会追上慢的指针,并且相遇的节点为环中的一个节点。然后再让指向相遇节点的指针绕着环一圈便可以计算出环的长度length。最后再让一个指针从链表头节点出发,另一个指针从链表的第length+1个节点出发,两个指针以相同速度往后移动,相遇的节点便为链表的环的入口节点。该思路过程体现了分解复杂问题为几个简单问题的思想。

代码(已在牛客网AC):

public ListNode EntryNodeOfLoop(ListNode pHead)
    {
       ListNode meetingNode = meetingNode(pHead);
       if(meetingNode == null)
           return null;
        // 计算环的长度
        int circleLength = 1;
        ListNode pNode1 = meetingNode;
        while(pNode1.next != meetingNode)
        {
            circleLength++;
            pNode1 = pNode1.next;
        }
        //寻找环的入口节点
        ListNode pNode2 = pHead;
        pNode1 = pHead;
        // 注意两个指针的距离为环的长度
        for(int i = 0; i < circleLength; i++)
            pNode1 = pNode1.next;
        while(pNode1 != pNode2)
        {
            pNode1 = pNode1.next;
            pNode2 = pNode2.next;
        }
        return pNode1;
    }

    // 该函数用于寻找一快一慢指针在环中相遇的节点
    private ListNode meetingNode(ListNode pHead)
    {
        if(pHead == null)
            return null;
        ListNode pSlow = pHead.next;
        // 若链表只有一个节点,则无环
        if(pSlow == null)
            return null;

        ListNode pFast = pSlow.next;
        while(pFast != null && pSlow != null)
        {
            if(pFast == pSlow)
                return pFast;
            pSlow = pSlow.next;
            if(pFast.next != null)
                pFast = pFast.next.next;
        }
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值