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