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?
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
方法一:利用 HashSet
利用 HashSet ,HashSet 中出现的第一个重复的元素就是链表中的环的头。
public ListNode detectCycle(ListNode head) {
Set<ListNode> nodeset = new HashSet<>();
while(head != null){
if(nodeset.contains(head)){
return head;
}
else{
nodeset.add(head);
head = head.next;
}
}
return head;
}
方法二:两个指针
这里设置了两个指针,一个速度快的指针,一个速度慢的指针。
设环的长度为 N ,进入环之前的距离为 A ,相遇时慢指针走过的距离为 B。
速度快的指针的速度是速度慢的指针的 2 倍,所以两个指针第一次相遇时,快的指针
正好比慢的指针多走了一倍的距离,也就是多走了一圈,即 A + B = N.
所以在第一个相遇之后,慢指针再移动 A 的距离就能到环的起点。
想象成下图比较好理解一些:
public ListNode detectCycle2(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if (fast == slow){
ListNode slow2 = head;
while (slow2 != slow){
slow = slow.next;
slow2 = slow2.next;
}
return slow;
}
}
return null;
}