题目描述
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:输入:head = [3,2,0,-4], pos = 1 输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
思路:
思路不对,学习他人的思路
1.首先先判断是否存在闭环,使用双指针快速查找是否存在闭环,然后再定位到闭环的起点
2.定位闭环的起点,引用他人的思路:
设置到入口距离为X,快慢指针交点为距离环入口L的位置
|<--- X ---->|<--L-->|
(1)-->(2)-->(3)---->(4)-->(5)
\ /
----------
环长为C
由于快慢指针走的距离差2倍
可以得到存在K使得
(X+L)*2=X+L+CK
其中K为相遇时循环过的次数
化简可得
X+L=CK -->X=CK-L;
即存在K使得X=CK-L
对于右边CK-L,
当K=1时右边=C-L,表示从节点(4)绕一圈走到节点(3)的距离
对右边可以认为是【节点(4)绕K圈走到节点(3)的距离】
左边X,正好是(1)到(3)的距离
左边可以认为是【节点(1)到节点(3)的距离】
结合等式表示,
存在K使得【节点(4)绕k圈到节点(3)的距离】等于【节点(1)到节点(3)的距离】
代码
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
//判断是否存在闭环
while(fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if(slow == fast) {
break;
}
}
//不存在闭环
if(fast == null || fast.next == null) {
return null;
}
fast = head;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
总结
思路很重要!!!