2025年- H38-Lc146 --142.环形链表(快慢指针,快2慢1,快1慢1)--Java版

1.题目描述

在这里插入图片描述

2.思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一步:判断是否有环
快慢指针(fast 每次走 2 步,slow 走 1 步);

如果 fast == slow,说明有环;

第二步:找环的起始节点
两指针:一个从头走,一个从相遇点走,每次走一步;

相遇点就是入环节点。

补充:
(1)在本题的求解过程中,双指针会产生两次“相遇”。
双指针的第一次相遇:
设两指针 fast,slow 指向链表头部 head 。
令 fast 每轮走 2 步,slow 每轮走 1 步。
(2)双指针第二次相遇:
令 fast 重新指向链表头部节点。此时 f=0,s=nb 。
slow 和 fast 同时每轮向前走 1 步。
当 fast 指针走到 f=a 步时,slow 指针走到 s=a+nb 步。此时两指针重合,并同时指向链表环入口,返回 slow 指向的节点即可。
模拟指针两次相遇的动态图

3.代码实现

 class ListNode {
      int val;
      ListNode next;

     public ListNode() {
     }

     ListNode(int x) {
          val = x;
          next = null;
      }

     public ListNode(int val, ListNode next) {
         this.val = val;
         this.next = next;
     }
 }
public class H142 {
    public ListNode detectCycle(ListNode head) {

        ListNode slow=head;
        ListNode fast=head;//一开始要同起点出发

        //1.存在空节点或者一个节点的,返回null
        if(head==null||head.next==null)
        {
            return null;
        }


        //3.开始执行快2慢1的操作
        while(fast!=null&&fast.next!=null)//不能是链表的情况,要同时存在。
        {

                fast=fast.next.next;
                slow=slow.next;
                if(fast==slow)//第一次相遇,说明存在环。快慢指针一起从原点出发
                {
                    //第二次相遇,快慢指针每次走一步
                    fast=head;//第二次相遇快指针从head开始走

                    while(fast!=slow)//用if和while都可以,说明p1和p2 第二次还没相遇
                    {
                        fast=fast.next;
                        slow=slow.next;
                    }
                    return fast;//如果p1=p2,说明此时快慢指针相遇。第二次相遇过程,慢指针叫p2,快指针叫p1
                }


        }
        return null;//说明无环

    }
        public static void  main(String[] args)
    {
        H142 test = new H142();

        // 构建链表:3 -> 2 -> 0 -> -4
        ListNode node4 = new ListNode(-4);
        ListNode node3 = new ListNode(0, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode head = new ListNode(3, node2);

        // 构建环:让 -4 指向 2,形成环
        node4.next = node2;

     ListNode res = test.detectCycle(head);
     System.out.print("输出返回链表开始入环的第一个节点的结果;");
     if (res != null) {
         System.out.print(res.val);
     }
     else
     {
         System.out.print("无环");
     }
 }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值