判断一链表是否有环,求环的第一个节点和环的长度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了判断一链表是否有环,求环的第一个节点和环的长度相关的知识,希望对你有一定的参考价值。

第一种方法:直接遍历时,用hashset存放,判断是否存在环

第二种方法:使用快慢指针

public class CycleLinkedList {

    public static void main(String[] args) {

        Node head = new Node(1);
        Node node3 = new Node(3);
        head.next = node3;
        head.next.next = new Node(5);
        head.next.next.next = new Node(7);
        head.next.next.next.next = new Node(9);
        head.next.next.next.next.next = node3;
        System.out.println("是否有环:" + hasCycle(head));
        Node enterNode = getEnterNode(head);
        System.out.println("环的入口:" + enterNode.value);
        System.out.println(getCycleSize(enterNode));

    }

    // 环的长度
    public static Integer getCycleSize(Node node) {
        Node start = node;
        int len = 1;
        while (node.next != start) {
            len++;
            node = node.next;
        }
        return len;
    }

    // 如果有环的话,慢指针和快指针一定会在环上的某个点相遇,但不一定是环的入口
    public static boolean hasCycle(Node head) {
        Node fast = head;
        Node slow = head;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast) {
                return true;
            }
        }
        return false;
    }

    // 环的入口节点
    public static Node getEnterNode(Node head) {
        // 先求出快慢指针的相遇点
        Node fast = head;
        Node slow = head;
        Node cross = null;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast) {
                cross = fast;
                break;
            }
        }
        // 从链表头部和相遇点开始,每次移动一个节点,他们相遇点就是环的入口
        Node start = head;
        while (start != null && cross != null) {
            if (start == cross) {
                return cross;
            }
            start = start.next;
            cross = cross.next;
        }
        return null;
    }

    public static class Node {

        Node next;
        int value;

        public Node(int value) {
            super();
            this.value = value;
        }
    }
}

 

 

以上是关于判断一链表是否有环,求环的第一个节点和环的长度的主要内容,如果未能解决你的问题,请参考以下文章

判断链表是否有环,环的入口以及环的长度

链表相关面试题:返回两个链表的第一个交点,判断单链表是否有环,返回入环的第一个结点

(转)求单链表是否有环,环入口和环长

数据结构与算法之深入解析如何确定单链表有环并求环的入口和长度

判断链表是否有环,并判断环的入口以及环的长度

判断链表是否有环,并判断环的入口以及环的长度