环形链表(1.判断是否是环形链表,2求环形的长度,3.求环形链表的入环节点)

这篇博客探讨了环形链表的相关问题,包括如何判断链表是否为环形,如何计算环的长度,以及如何找到环的起始节点。提供了两种方法,一种利用HashSet的无重复性,另一种使用快慢指针。对于环形链表的进阶问题,通过快慢指针的相遇点可以确定环的长度,并进一步找到入环节点的位置。
摘要由CSDN通过智能技术生成

环形链表

环形链表—力扣链接

题目内容:给定一个链表,判断链表中是否有环
输入输出示例:true
在这里插入图片描述

1.代码实现

方法一:利用HashSet的无重复性
public static boolean hasCycle2(ListNode head) {
        //思路二:;利用HashSet的无重复性
        if(head == null )return false;
        Set<ListNode> set = new HashSet<>();
        while (head != null){
            if (set.contains(head)){
                return true;
            }
            set.add(head);
            head = head.next;
        }
        return false;
    }
方法二:快慢指针
public static boolean hasCycle2(ListNode head) {
        //思路一:比较好想到的思路就是快慢指针
        if(head == null )return false;
        ListNode quick = head.next;
        ListNode cur = head;
        while (cur != quick){
            if (quick == null || quick.next ==null){
                return false;
            }
            cur = cur.next;
            quick = quick.next.next;
        }
        return true;
    }
        

2.环形链表进阶(1)

  • 如果是环形链表,如何知道环形的长度

思路分析:利用上面的快慢指针,继续前行在一次相遇,中间的移动次数,就是长度;

//求环形链表的长度(扩展)
    public static int hasCycleLength(ListNode head) {
        if(head == null )return 0;
        ListNode quick = head.next;
        ListNode cur = head;
        while (cur != quick){
            if (quick == null || quick.next ==null){
                return 0;
            }
            cur = cur.next;
            quick = quick.next.next;
        }
        //循环中出来说明第一次相遇;那么继续
        int count = 1;//因为有环,最少也有一个节点
        quick = quick.next;
        while (cur != quick){
            cur = cur.next;
            quick = quick.next.next;
            count++;
        }
        return count;
    }

3.环形链表进阶(2)

  • 返回环形链表的起始节点(就是入环节点)

解题思路:重新拿一个节点从头开始遍历,另外一个节点p1从相遇点前进,则相遇点就是入环节点

public static ListNode firstNode(ListNode head){
        //双指针的方法,一个的移动速度是另外一个移动速度的二倍
        ListNode p1 = head;
        ListNode p2 = head;
        ListNode p3 = head;
        System.out.println(p3);
        while(p2 != null && p2.next != null) {//这里只需要判断p2就可以,因为p2移动的快
            p1 = p1.next;
            p2 = p2.next.next;
            if (p1 == p2){
                break;//相等则有环,类似于小学的追击问题,就像操场跑步一样,一直跑下去,跑的快一定会追上跑的慢的
            }
        }
        //出来要判断一下
        if (p2 != null){
            //如果p2不等于空,则说明是相遇了,才从循环中出来的
            //则在次进行循环
            while (true){
                p1 = p1.next;
                p3 = p3.next;
                if (p1 == p3){
                    System.out.println(p3);
                    return p3;
                }
            }
        }
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值