困难 带环链表 II
36%
通过
给定一个链表,如果链表中存在环,则返回到链表中环的起始节点的值,如果没有环,返回null。
您在真实的面试中是否遇到过这个题?
Yes
样例
给出 -21->10->4->5, tail connects to node index 1,返回10
挑战
不使用额外的空间
/**
* 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) {
if (head == null || head.next==null) {
return null;
}
ListNode fast, slow;
fast = head.next;
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;
}
}
关于求链表的开始节点:
假设相遇的位置为x,快慢指针在x+z处相遇,环的长度是y,则,因为慢指针每走一步,快指针走两步,所以两者相遇时,快指针走的时慢指针的两倍,而且可能套了k圈,所以有:2(x+z)-(x+z)=k*y.得:x=k*y-z
现在要求环开始的位置,假设两个有指针,一个从链表头开始(0),一个从相遇位置开始(x+z),则两者会在环开始的位置相遇,因为:
0+x = k*y -z
x+z+x = 2x+z = 2(k*y-z)+z=2k*y-z=k*y-z;