链表中环的入口节点

题目描述

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

解题思路

思考一个更简单的问题

查找链表中是否有环的方法

  1. 如果链表长度等于1或2直接返回否

  2. 设置两个节点,分别为p1=root.next、p2root.next.next

  3. 循环
    ==》 每次使p1前进一步,p2前进两步

  4. 若发现p1与p2相等,则返回true

  5. 若发现p1或p2为空,则返回false

这道题是问题a的延伸,首先要确定是否有环,若有环,找出环的入口节点

假设我们有如下一个链表:
链表

解题过程与思路:

例子的推导

我们在上图中的推导中证明的是:p1、p2第一次相遇位置与环入口节点的距离,等于根节点与环入口节点的距离。

整个链表不重复节点为11个,因为有环的存在,所以不重复的路径也为11(5+6)个。相遇时p1走了6步,p2走了12步,都在6的位置,而且相遇点距离环入口节点相差5步。

所以讲p2重新指向root(节点0),并改为一次循环走一步,下次相遇p1,p2相遇的位置就是入口节点啦~

下面是通用的推导过程:

重点就是这个证明,证明出来了,解题方法就能说的通了

证明:p1、p2第一次相遇的位置与环入口节点的距离,等于根节点与环入口节点的距离
通用解题思路的推导

代码

/*
 public class ListNode {
    int val;
    ListNode next = null;
 
    ListNode(int val) {
        this.val = val;
    }
}
*/
 
 
public class Solution {
  
    ListNode EntryNodeOfLoop(ListNode pHead){
        if(pHead == null || pHead.next == null)
            return null;
        ListNode p1 = pHead;
        ListNode p2 = pHead;
        while(p2 != null && p2.next != null ){
            p1 = p1.next;
            p2 = p2.next.next;
            if(p1 == p2){
                p2 = pHead;
                while(p1 != p2){
                    p1 = p1.next;
                    p2 = p2.next;
                }
                if(p1 == p2)
                    return p1;
            }
        }
        return null;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值