题目
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始 )。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:

ini
输入: head = [3,2,0,-4], pos = 1
输出: 返回索引为 1 的链表节点
解释: 链表中有一个环,其尾部连接到第二个节点。
题解
方式一:哈希表
哈希表第二次遇到同一个节点一定是环入口节点
复杂度:O(n)
java
public ListNode detectCycle(ListNode head) {
HashSet<ListNode> set = new HashSet<>(); // 去重
while (head != null) {
if (set.contains(head)) {
return head;
}
set.add(head);
head = head.next;
}
return null;
}
方式二:双指针
双指针相遇的位置一定在环中,但不一定是环入口
复杂度:O(n)
java
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null) {
slow = slow.next;
if (fast.next != null) {
fast = fast.next.next;
} else {
return null;
}
// 环中相遇,计算得出slow到环入口的距离等于起点到环入口的距离
if (slow == fast) {
ListNode ptr = head;
while (ptr != slow) {
slow = slow.next;
ptr = ptr.next;
}
return ptr;
}
}
return null;
}
总结
算法:双指针
数据结构:哈希表