Description:
给定一个链表,如果链表中存在环,则返回到链表中环的起始节点的值,如果没有环,返回null。
Explanation:
给出 -21->10->4->5,
tail connects to node index 1(最后一个node又指向10),返回10
Solution:
Use two pointers.One moves one node once, the other moves two nodes each. If two pointer can meet, the list node has a circle.
Then the fast one points to the head, and both pointers move one node once. When two pointers meet, the current node is the start of circle.
prove:take the explanation.
Both pointers start from head node.
The slow point needs to move four times to meet the fast one, so the slow pointer passed 5 nodes(include the head),the fast one passed 9 nodes;
the difference is the length of circle, and the number of the fast one passed nodes subtract double length of circle is the length of the nodes before circle.
the circle length:9 - 5 = 4;
the length of nodes before circle: 9 - 4*2 = 1;---> named len now
The first meeting, the node that slow pointer pointed is len far away from the start of circle.
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The first node of linked list.
* @return: The node where the cycle begins.
* if there is no cycle, return null
*/
public ListNode detectCycle(ListNode head) {
// write your code here
if(head == null || head.next == null) return null;
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast) break;
}
if(fast != null && fast == slow){
fast = head;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
return null;
}
}