141. Linked List Cycle
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
链表是否存在环
Set解法
public boolean hasCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
while (head != null) {
if (!set.add(head))
return true;
head = head.next;
}
return false;
}
快慢指针:
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast==slow)
return true;
}
return false;
}
142. Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
Set解法
public ListNode detectCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
while (head != null) {
if (!set.add(head))
return head;
head = head.next;
}
return null;
}
快慢指针
感谢:http://www.jianshu.com/p/ce7f035daf74 解析
![](https://i-blog.csdnimg.cn/blog_migrate/a7d70c0e6f280e7f406b59ce3c3b1349.webp?x-image-process=image/format,png)
142.LinkedListCycleII
图中,
X
是链表的起点。Y
是环的起点。Z
是fast
和slow
首次相遇的地方(二者同时从X出发,slow
每次移动一步,fast
每次移动两步)。a
,b
,c
分别表示XY
(蓝色),YZ
(红色),ZY
(绿色)的长度。
当fast
和slow
在Z
点首次相遇时:
fast
移动的距离是:a + b + c + bslow
移动的距离是:a + b
因为fast
的移动速度是slow
的两倍,所以:
(a + b + c + d) == 2 * (a + b)
由此可以推出:
a == c
我们需要用上面的推论来寻找环的起点(Y
)。
当fast
和slow
首次相遇时,我们就到了Z
点。
由于a == c
,也就是X
到Y
与 Z
到Y
的距离相等。
因此,如果我们让指针p
和q
分别从X
和Z
出发,并且每次都移动一步,当它们相遇时,恰好就是环的起点Y
。
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
fast = head;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
return null;
}