Linked List Cycle I
Problem
Given a linked list, determine if it has a cycle in it.
Example
Given -21->10->4->5
, tail connects to node index 1
, return true
Note
做法:如果有环,快慢指针必定可以相遇。
注意两点:初始化快慢指针的时候,fast
要在slow
后面,也就是head.next
;由于fast
一次走两步,所以while
循环里要判断两个位置是否为null
:fast
和fast.next
。
Solution
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) {
if (fast == null || fast.next == null) return false;
fast = fast.next.next;
slow = slow.next;
}
return true;
}
}
Linked List Cycle II
Problem
Given a linked list, return the node where the cycle begins.
If there is no cycle, return null
.
Example
Given -21->10->4->5
, tail connects to node index 1
,return 10
.
Note
画一个简图:
a: length of non-loop 非环直线的长度
b: length of loop 环的长度
x: the point slow and fast meet in the loop 快慢指针在环内相遇的位置
--------oooo
o o
ooxo
(a+x)*2 = a-1+kb+x --> a = kb-1-x
, slow needs to go kb-x longer to finish the loop.
so if head
wants to go to the start point of the loop, it would pass a
, the same for slow
. After head
went a
, slow
went kb-x-1
. However, a = kb-x-1
, so head
is slow.next
at the loop, which is the start point of the loop.
slow在fast在环里的k处相遇,fast比slow走了两倍的路程,假设非环路和环路长度分别为a和b,且fast已经在环里多走了k圈,所以:(a+x)*2 = a-1+kb+x --> a = kb-1-x
此时,slow还要走kb-x
才能走完整个环。
而让head此时重新从起点出发,以和slow相同的速度,需要走非环路的直线长度a
,才能到达环的起点。
那么,head到达环的时候,走了a = kb-1-x
:是slow在环内走到环的起点的路程-1。
也就是说,slow.next = head
,就是第二个while循环结束的条件。
Solution
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null) return null;
ListNode fast = head.next;
ListNode slow = head;
while (fast != slow) {
if (fast == null || fast.next == null) return null;
fast = fast.next.next;
slow = slow.next;
}
while (head != slow.next) {
head = head.next;
slow = slow.next;
}
return head;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。