题目
给定一个链表,返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
提示:
链表中节点的数目范围在范围 [0, 104] 内
-105 <= Node.val <= 105
pos 的值为 -1 或者链表中的一个有效索引
进阶:是否可以使用 O(1) 空间解决此题?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/c32eOV
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
解法一:使用hashmap来记录节点是否被访问过,当有重复访问时即环的入口
解法二:快慢指针。fast时slow运转的2倍,fast:a+b+n(b+c),slow:a+b,fast=2slow.=>a=c+(n-1)(b+c),即fast和slow相遇时,head到环入口的距离刚好等于slow从相遇点走到环入口+整圈的路程。
代码:
该代码存在问题,输入为[1,2] -1时,fast.next!=null,但是fast=fast.next.next,此时fast=null,不存在fast.next,while(fast.next!=null)会运行报错。(关于链表可以多尝试写当前结点!=null来判断)
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null) return null;
ListNode fast=head,slow=head;
while(fast.next!=null) {
slow=slow.next;
fast=fast.next.next;
if(fast==slow) {
ListNode ptr=head;
while(ptr!=slow) {
slow=slow.next;
ptr=ptr.next;
}
return ptr;
}
}
return null;
}
}
修改之后的代码:
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null) return null;
ListNode fast=head,slow=head;
while(fast!=null) {
slow=slow.next;
if(fast.next!=null)
fast=fast.next.next;
else return null;
if(fast==slow) {
ListNode ptr=head;
while(ptr!=slow) {
slow=slow.next;
ptr=ptr.next;
}
return ptr;
}
}
return null;
}
}