
快慢指针版本一
public class Solution {
// 使用快慢指针法,快指针每次走两步,慢指针每次走一步,如果链表有环,则快慢指针一定会相遇
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) return false;
// 快指针
ListNode fast = head.next;
// 慢指针
ListNode slow = head;
while (fast != slow) {
// 如果为空,说明跑完了,没有环,返回 false
if (fast == null || fast.next == null) return false;
fast = fast.next.next;
slow = slow.next;
}
return true;
}
}
快慢指针版本二
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) return false;
// 慢指针
ListNode fast = head.next;
// 快指针
ListNode slow = head;
// 如果快指针与快指针的下个节点都不为空,则继续遍历
// 为什么判断快指针?因为快指针先到达终点,如果链表没有环,到终点时为空
while (fast != null && fast.next != null) {
// 如果快指针与慢指针相等,说明相遇了,返回 true
if (fast == slow) return true;
slow = slow.next;
fast = fast.next.next;
}
return false;
}
}
使用 set 存放节点
public class Solution {
// 使用一个 set 记录遍历过的节点
public boolean hasCycle(ListNode head) {
if (head == null) return false;
Set<ListNode> set = new HashSet<>();
while (head != null) {
// 如果节点在 set 中,说明有环
if (set.contains(head)) return true;
set.add(head);
head = head.next;
}
return false;
}
}