解法一:哈希表

用哈希表存储访问过的结点,如果出现重复访问说明存在环。

  1. /**
  2. * Definition for singly-linked list.
  3. * class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) {
  7. * val = x;
  8. * next = null;
  9. * }
  10. * }
  11. */
  12. public class Solution {
  13. public boolean hasCycle(ListNode head) {
  14. Set<ListNode> set = new HashSet<>();
  15. while (head != null) {
  16. if (set.contains(head)) {
  17. return true;
  18. }
  19. set.add(head);
  20. head = head.next;
  21. }
  22. return false;
  23. }
  24. }

解法二:快慢指针

两个指针以不同的速度遍历,一个步长为1,一个步长为2。如果存在环,就像操场上跑步一样,步长大的跑得快,会在某一时刻追上步长小的。

  1. /**
  2. * Definition for singly-linked list.
  3. * class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) {
  7. * val = x;
  8. * next = null;
  9. * }
  10. * }
  11. */
  12. public class Solution {
  13. public boolean hasCycle(ListNode head) {
  14. ListNode p1 = head;
  15. ListNode p2 = head;
  16. while ((p1 != null) && (p2 != null)) {
  17. p1 = p1.next;
  18. if (p1 != null) {
  19. p1 = p1.next;
  20. } else {
  21. break;
  22. }
  23. p2 = p2.next;
  24. if (p1 == p2) {
  25. return true;
  26. }
  27. }
  28. return false;
  29. }
  30. }