剑指Offer23:链表中环的入口节点

#题目:给一个链表,若其中包含环,请找出该链表的环的入口节点,否则,输出null。
思路:解决这个问题的第一步是先确定链表是否有环,有的话,我们计算出链表环的长度,否则直接返回null。在计算出环的长度n后,我们设置两个指针pNode1、pNode2指向链表的头节点,然后让pNode1先走n步后,再让pNode1与pNode2同时移动,相遇点就是链表中环的入口节点了。
为什么这种方法可以得到入口节点?因为链表的总长度=环长度+无环段长度,pNode1一共走了总长度,pNode1走完环长度,pNode2在相遇前走的长度就是无环段长度,所以相遇的地方就是入口节点了。
还有我们要如何求得环的长度呢?把一个节点指向meetingNode进行遍历比较然后再计数就可以了。
有了清晰的思路之后,我们便可以写出以下代码了:

public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        ListNode meetingNode=MeetingNode(pHead);
        if (meetingNode==null)
            return null;
        int loopSum=1;//由于是判断tmp.next!=meetingNode,所以loopSum应初始化为1
        ListNode tmp=meetingNode;
        
        //计算环的长度
        while (tmp.next!=meetingNode)
        {
            tmp=tmp.next;
            loopSum++;
        }

		ListNode pNode1=pHead,pNode2=pHead;
        
        //pNode1先走环的长度步数
        while (loopSum>0)
        {
            pNode1=pNode1.next;
            loopSum--;
        }
        
        //两个指针一起移动
        while (pNode1!=pNode2)
        {
            pNode1=pNode1.next;
            pNode2=pNode2.next;
        }
        return pNode1;
    }

	//获取快慢指针在环中相遇的节点
    private ListNode MeetingNode(ListNode pHead)
    {
        ListNode fast=pHead;//快指针
        ListNode slow=pHead;//慢指针
        while (fast!=null && fast.next!=null)//注意要考虑fast的双重边界条件
        {
            fast=fast.next.next;
            slow=slow.next;
            if (slow==fast)
                return slow;
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值