/**
* 自己的代码
* 快慢指针,到null则return null,否则有环
* 将一个指针重置为head,另一个在第一次相遇的位置不动,两个指针同时出发都以一步速度走,再次相遇的位置为环的入口
* Runtime: 0 ms, faster than 100.00%
* Memory Usage: 39.3 MB, less than 34.62
*/
// 写法一
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
do {
if (fast == null || fast.next == null)
return null;
fast = fast.next.next;
slow = slow.next;
} while (fast != slow);
fast = head;
while (slow != fast) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
}
// 写法二
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return fast;
}
}
return null;
}
}
/**
* 自己的代码2
* 只用一个指针遍历链表,用set保存每一个遍历过的节点,当add结果为false说明节点重复,重复的节点就是环的入口
* Runtime: 3 ms, faster than 24.70%
* Memory Usage: 39.9 MB, less than 17.87%
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
while (head != null) {
if(!set.add(head))
return head;
head = head.next;
}
return null;
}
}