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


    第一种方法:直接遍历时,用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;
            }
        }
    }

  • 相关阅读:
    Codeforces Round #535 (Div. 3) 1108C
    Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering
    Leetcode--136. Single Number(easy)
    Leetcode--572. Subtree of Another Tree(easy)
    Leetcode--101. Symmetric Tree(easy)
    Leetcode--680. Valid Palindrome II(easy)
    2017百度之星资格赛 1003 度度熊与邪恶大魔王 背包DP
    台州 OJ 1704 Cheapest Palindrome 回文 区间DP
    洛谷 P1019 单词接龙 深搜
    UVA 11882 Biggest Number 深搜 剪枝
  • 原文地址:https://www.cnblogs.com/moris5013/p/11640652.html
Copyright © 2020-2023  润新知