142J. Linked List Cycle II
https://leetcode.com/problems/linked-list-cycle-ii/
愚蠢方法
用 HashMap 秒杀,HashSet同理。 HashMap还适用于要求返回index的情况。
public class Solution {
public ListNode detectCycle(ListNode head) {
Map<ListNode, Integer> map = new HashMap<>();
ListNode p = head;
int i = 0;
while(p!=null){
if(map.containsKey(p)){
return p;
}
map.put(p,i);
p = p.next;
i+=1;
}
return null;
}
}
机智方法
快慢指针,若慢指针走了 n 步,则快指针走了 2n。 如果没有Loop不说了,如果有的话,假设loop部分长度为 b, 假设loop开始前长度为 a。 则List的长度是 a + b. 假设相遇在 a + c 处,则慢指针走了 a + c 步,而快指针 走了 a + b + c步。 a + c = n, a + b + c = 2n,解得 b = n = a + c。所以 实际List长度是 a + c + a 这么分割的。快慢数组相遇在 a + c 处。这时令一个指针重新 指向头部/dummyhead,一起移动 a 步就相遇了。此时的位置就是正确的。
注意代码中我们为了简便处理边界情况,直接使用了dummyhead。非常优秀。 </pre>
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode dummyhead = new ListNode(-1);
dummyhead.next = head;
ListNode slow = dummyhead;
ListNode fast = dummyhead;
while(fast!=null&&fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast) break;
}
if(fast == null || fast.next == null){
return null;
}else{
slow = dummyhead;
while(slow!=fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
}
Last updated
Was this helpful?