给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
当两个人起点不同,目标相同时,假设两个人完成目标有一段必走的路程,如果两个人完成目标的路程一样远,那么必会在必走路的起点相遇。
/**当有圈的时候
* 当慢指针 与快指针相遇的时候 假设 慢指针走了 L1 的长度 此时 快指针走了 2*L1 的长度
* 快指针 比 慢指针 多走了 n圈 即 2*L1 - L1 = L1 = n * L ( L:圈的长度 L1:从头节点到相遇节点的距离 )
* 从相遇节点 开始 再继续走 L1的距离,依然会回到相遇节点 并且从 头节点开始走 L1的距离,也会到相遇节点
* 假设第一个 入圈 节点 到相遇节点的距离 是 B(这个我们不知道具体是多少)
* 从头节点走 L1-B 的距离 就正好是入圈的第一个节点 从相遇节点 走 L1-B 的距离 也正好是入圈的第一个节点
* 但是 B 我们无法得知,但是如果从头节点 与 相遇节点 同时开始走,第一个相遇的节点肯定是入圈的节点,因为 头节点到相遇节点的距离和相遇节点出发回到相遇节点的距离是一样的,所以肯定会相遇
* 距离,就类似于 一个 人 字
* 从 人 字 的两边出发,到上面的距离如果一样远,那么同步出发,那么肯定会在交点相遇
* @param head
* @return
*/
public ListNode detectCycleII(ListNode head){
if(head==null || head.next==null)
return null;
ListNode slow = hasCycle(head);
if(slow!=null){
ListNode q = head;
while (q!=slow){
q = q.next;
slow = slow.next;
}
return slow;
}
return null;
}//0ms 100%
public ListNode hasCycle(ListNode head){
ListNode fast = head;
ListNode slow = head;
while (fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(slow==fast)
return slow;
}
return null;
}