image.png

    1. static class Node{
    2. int val;
    3. Node next;
    4. public Node(int val, Node next) {
    5. this.val = val;
    6. this.next = next;
    7. }
    8. }
    9. public static void main(String[] args) {
    10. Node node5 = new Node(5, null);
    11. Node node4 = new Node(4, node5);
    12. Node node3 = new Node(3, node4);
    13. Node node2 = new Node(2, node3);
    14. Node node1 = new Node(1, node2);
    15. node5.next = node3;
    16. System.out.println(hasCycle(node1));
    17. }
    18. /**
    19. * 使用集合存储已经遍历过的元素,如果再次遍历到则返回
    20. * 时间复杂度O(n),空间复杂度也是O(n)
    21. * @param node1
    22. * @return
    23. */
    24. private static boolean hasCycle(Node node1) {
    25. // 定义一个set存储已经遍历过的节点
    26. Set<Node> nodeSet = new HashSet<>();
    27. // 循环链表
    28. while (null != node1) {
    29. // 如果set中已存在node节点,再次add则返回false
    30. if (!nodeSet.add(node1)) {
    31. return true;
    32. }
    33. node1 = node1.next;
    34. }
    35. return false;
    36. }
    1. static class Node{
    2. int val;
    3. Node next;
    4. public Node(int val, Node next) {
    5. this.val = val;
    6. this.next = next;
    7. }
    8. }
    9. public static void main(String[] args) {
    10. Node node5 = new Node(5, null);
    11. Node node4 = new Node(4, node5);
    12. Node node3 = new Node(3, node4);
    13. Node node2 = new Node(2, node3);
    14. Node node1 = new Node(1, node2);
    15. // node5.next = node3;
    16. System.out.println(hasCycle2(node1));
    17. }
    18. /**
    19. * 使用双指针,快指针一次前进2个节点,慢指针一次前进一个节点,如果存在环,则这两个指针就一定会相遇
    20. * 时间复杂度是O(n),空间复杂度是1
    21. * @param node1
    22. * @return
    23. */
    24. private static boolean hasCycle2(Node node1) {
    25. if (null == node1) {
    26. return false;
    27. }
    28. // 定义两个指针,一个慢指针slow,一个快指针quick
    29. Node slow = node1, quick = node1.next;
    30. while (slow != quick) {
    31. // 如果快指针为null或者快指针的下一个节点为null,说明到链表的结尾,那么也不存在环,返回false
    32. if (null == quick || null == quick.next) {
    33. return false;
    34. }
    35. slow = slow.next;
    36. quick = quick.next.next;
    37. }
    38. // 如果慢指针和快指针相等,则存在环,返回true
    39. return true;
    40. }