题目描述

方法一;快慢指针
- 快慢指针一定在环内相遇,
- 原因:快指针会在圈内一直绕,当慢指针进入圈后,快指针会追赶慢指针,直到套圈。并且慢指针最多走完一个圈的距离。
- 慢指针肯定不会走多圈,会在一圈之内被追上。
- 假设fast在slow前x个单位,假设环长度为L, fast需要追赶L-x长度,追赶的速度为2-1=1,追赶上所花费的时间为L-x/1 = L-x。在这段时间内,slow走的距离为 1 * (L-x) = L - x, 永远小于L,因此slow不可能走完一整个环。

- 所以,再用两个指针,一个从头节点开始走,另一个从相遇点开始走,两者相遇处即为入环处。
public class Solution {
public ListNode detectCycle(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) {
while (fast != head) {
fast = fast.next;
head = head.next;
}
return head;
}
}
return null;
}
}
方法二:用set记录访问过的节点
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
ListNode cur = head;
while (cur != null){
if (set.contains(cur)) {
return cur;
} else {
set.add(cur);
cur = cur.next;
}
}
return null;
}
}