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

环形链表

环形链表—力扣链接

题目内容:给定一个链表,判断链表中是否有环
输入输出示例: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;
    }

猜你喜欢

转载自blog.csdn.net/qq_45665172/article/details/113845248