142.环形链表II--力扣---java

目录

题目描述:

1、判断链表是否有环

 快慢指针法

 2、找环的入口


题目描述:

给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表没有环,则返回null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改链表。

 题目链接:142. 环形链表 II - 力扣(LeetCode)

这个题主要考察了两个点:

1、判断链表是否有环

2、如果有环,怎么才能找到这个环的入口

1、判断链表是否有环

 快慢指针法

分别定义fast和slow指针,同时从头结点出发,fast每次走两个结点,slow每次走一个结点,如果两个指针相遇,则说明这个链表有环。

解释:可以自己试着画下图,无论怎么走都会出现fast是slow前一个结点这种情况,这两个指针再各自走一步就会相遇。

 知道思路后,也可以尝试写下面这道题

题目链接:141. 环形链表 - 力扣(LeetCode)

 2、找环的入口

通过第一步操作,我们已经知道了这个链表是否有环,如果有,那么该如何找到环的入口呢? 

我们可以将本题抽象为一个数学题,假设a点为两指针相遇点,b点为该环的入口,也是本题中要求的结点,c点为头结点,根据下图的解释,得出了一个数学公式:x=(k-1)*(m+n)+n

(m+n)就是环的周长,当k=1的时候,说明fast指针在环里转了一圈然后与slow指针相遇,此时上述的数学公式就可以化简为 x=n 。也就是说,一个指针从a点出发,另一个指针从c点出发,两个指针每次都只走一个结点,他两相遇的那个结点就是我们所要求的入口结点。

 总结:用快慢指针法判断是否有环,如果有环,得到相遇结点a,再设置两个指针ans和cur同时从a点和c点出发,那么他们相遇的结点b点就是环形入口的结点。

代码如下:

public class Solution {
    //找a点
    public ListNode hasCycle(ListNode head) {
        ListNode fast=head;
        ListNode slow=head;
        //fast走的快,fast为null则说明,该链表没有环
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            //相等即有环,返回相遇点a
            if(fast==slow){
                return slow;
            }
        }
        return null;
    }
    
    //找b点
    public ListNode detectCycle(ListNode head) {
        ListNode ans=hasCycle(head);  //记录相遇点
        ListNode cur=head;    
        //没有环返回null
        if(ans==null){
            return null;
        }
        while(cur!=ans){
            cur=cur.next;
            ans=ans.next;
        }
        return cur;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值