hot 100 第二十六题 26.环形链表 II

题目:

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 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
解释:链表中没有环。

核心思路

快慢指针两阶段法

  1. 第一阶段:快慢指针找到相遇点(证明有环)

  2. 第二阶段:一个指针从头开始,一个从相遇点开始,再次相遇的地方就是环入口

    链表:
    1 → 2 → 3 → 4 → 5
    ↑ ↓
    └───────────┘
    环入口是节点2

题解:

java 复制代码
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) return null;
        
        // 第一阶段:快慢指针找相遇点
        ListNode slow = head;
        ListNode fast = head;
        
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            
            if (slow == fast) {
                // 找到相遇点,进入第二阶段
                // 一个指针从头开始,一个从相遇点开始
                ListNode ptr1 = head;
                ListNode ptr2 = slow;
                
                while (ptr1 != ptr2) {
                    ptr1 = ptr1.next;
                    ptr2 = ptr2.next;
                }
                
                return ptr1;  // 环的入口
            }
        }
        
        return null;  // 无环
    }
}
```

## 数学原理(重要!)

### 设定变量
```
链表结构:
head → ... → 入口 → ... → 相遇点 → ... → 入口
       a步      b步      c步

a: 起点到入口的距离
b: 入口到相遇点的距离
c: 相遇点回到入口的距离
环长 L = b + c
```

### 推导过程
```
第一次相遇时:

慢指针走的距离: a + b
快指针走的距离: a + b + n * L  (n是快指针在环内转的圈数)

因为快指针速度是慢指针的2倍:
2 * (a + b) = a + b + n * L

化简:
2a + 2b = a + b + n * L
a + b = n * L
a = n * L - b
a = n * (b + c) - b
a = (n - 1) * (b + c) + c
a = (n - 1) * L + c

结论:
从起点走 a 步 = 从相遇点走 c 步 + (n-1)圈

所以:
- 一个指针从 head 出发
- 一个指针从相遇点出发
- 两者每次走1步,会在环入口相遇!
```

## 详细演示
```
链表:
3 → 2 → 0 → -4
    ↑        ↓
    └────────┘

a = 1 (head到入口:3→2)
b = 1 (入口到相遇点可能是:2→0)
c = 2 (相遇点回到入口:0→-4→2)
L = 3 (环长:2→0→-4→2)

第一阶段: 找相遇点
------------------
初始:
slow = 3
fast = 3

第1次移动:
slow: 3 → 2
fast: 3 → 2 → 0

slow = 2
fast = 0

第2次移动:
slow: 2 → 0
fast: 0 → -4 → 2

slow = 0
fast = 2

第3次移动:
slow: 0 → -4
fast: 2 → 0 → -4

slow = -4
fast = -4
相遇!

第二阶段: 找环入口
------------------
ptr1 = head = 3
ptr2 = slow = -4

第1次移动:
ptr1: 3 → 2
ptr2: -4 → 2

ptr1 = 2
ptr2 = 2
相遇!

返回 节点2(环入口)
```

## 图解过程
```
链表:
     入口
      ↓
1 → 2 → 3 → 4 → 5
    ↑           ↓
    └───────────┘

步骤1: 快慢指针找相遇点
--------------------
slow每次1步,fast每次2步

假设在节点4相遇:
    入口
      ↓
1 → 2 → 3 → 4 → 5
    ↑       ↑   ↓
    └───────┴───┘
            相遇点

步骤2: 从head和相遇点同时出发
--------------------
ptr1从1出发,ptr2从4出发,每次各走1步

ptr1: 1 → 2
ptr2: 4 → 5 → 2
          ↑
      相遇在入口!
```

## 为什么第二阶段要这样走?

### 直观理解
```
验证数学推导 a = c + (n-1)L:

从head到入口的距离 = a
从相遇点绕环回到入口的距离 = c

因为 a = c + (n-1)L
所以从head走a步到入口
  = 从相遇点走c步到入口 + 再转(n-1)圈

两个指针每次都走1步:
- ptr1走a步到达入口
- ptr2走c步+(n-1)圈也到达入口
- 所以两者在入口相遇!
```

### 特殊情况:n=1
```
当快指针只转了1圈就相遇(最常见):
a = c

这时:
- 从head走到入口的距离
- 等于从相遇点走到入口的距离
- 两者必然同时到达入口
```

## 完整示例

### 示例1
```
链表:
3 → 2 → 0 → -4
    ↑        ↓
    └────────┘

第一阶段:
slow和fast在某处相遇(假设在-4)

第二阶段:
ptr1从3开始: 3 → 2
ptr2从-4开始: -4 → 2

在节点2相遇 ✓(环入口)
```

### 示例2
```
链表:
1 → 2
↑   ↓
└───┘

第一阶段:
slow和fast在2相遇

第二阶段:
ptr1从1开始: 1
ptr2从2开始: 2 → 1

在节点1相遇 ✓(环入口)
```

### 示例3(无环)
```
链表: 1 → 2 → 3 → null

第一阶段:
fast到达null,没有相遇
直接返回 null
相关推荐
闻缺陷则喜何志丹几秒前
【动态规划】P3609 [USACO17JAN] Hoof, Paper, Scissor G
c++·算法·动态规划·洛谷
leihefeng31 分钟前
手写数字识别:KNN vs 逻辑回归实战
python·算法·机器学习·逻辑回归·scikit-learn
全栈技术负责人1 小时前
DeepSeek Harness 业务工具权限插件 dsh-tool-permission设计思路
网络·算法·ai·ai编程
mmmmath_31 小时前
面试题 02.07. 链表相交
算法·链表
residual_fan2 小时前
特征级SMOTE(Feature-level SMOTE)论文分享
人工智能·算法·数据挖掘·数据分析
xxwxx__2 小时前
深入理解 C++ STL:stack、queue 与 deque 从使用到底层实现全解析
开发语言·c++·算法
sylviiiiiia2 小时前
Leetcode hot100 多数元素/相交链表/反转链表
算法·leetcode·链表
CoderYanger2 小时前
A.每日一题:3622. 判断整除性
java·程序人生·算法·leetcode·面试·职场和发展·蓝桥杯
rannn_1112 小时前
【力扣hot100】动态规划专题|70、118、198、279、322、139、300、152、416、32
算法·leetcode·动态规划
渡之2 小时前
ArduPilot(APM)滤波器之 HarmonicNotchFilter 深度解析
算法·无人机