题目描述
方法一:HashSet记录访问过的节点
public class Solution {
public boolean hasCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
ListNode cur = head;
while (cur != null){
if (set.contains(cur)) {
return true;
} else {
set.add(cur);
cur = cur.next;
}
}
return false;
}
}
方法二:快慢双指针。
如果有环,那么快慢指针必然在环中相遇
数学归纳法证明:
1:快指针与慢指针之间差一步。此时继续往后走,慢指针前进一步,快指针前进两步,两者相遇。
2:快指针与慢指针之间差两步。此时唏嘘往后走,慢指针前进一步,快指针前进两步,两者之间相差一步,转化为第一种情况。
3:快指针与慢指针之间差N步。此时继续往后走,慢指针前进一步,快指针前进两步,两者之间相差(N+1-2)-> N-1步。
- fast可以一次走三步吗?不一定。
- 需要维持相对速度为1,这样可以逐渐缩小间距直到相遇
- 如果相对速度》1,可能会skip,死循环
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head, slow = head;
while (fast != null && fast.next != null && slow != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
return true;
}
}
return false;
}
}