LeetCode面试HOT100——160. 相交链表

相交链表双指针最优解

相交链表代码超详细解析(双指针最优解)

这段代码是力扣「相交链表」问题的 双指针最优解(时间复杂度O(n+m)、空间复杂度O(1)),核心思路是「让两个指针走相同的总路程,最终在相交节点相遇」。下面从「问题本质→代码逻辑→分步演示→关键细节」帮你彻底吃透。

一、先明确问题本质

1. 相交链表的定义

两个链表相交,指的是 节点引用相同(不是值相同),即从相交节点开始,后续所有节点都完全共用(结构上是"Y"形,不是"X"形)。

例:链表A:1→2→3→4→5,链表B:6→7→3→4→5,相交节点是3(两个链表的3是同一个节点,后续45也共用)。

2. 核心痛点

两个链表长度可能不同(设为n和m),直接遍历无法同步到达相交节点。

常规思路(如哈希表存节点)需要额外空间,而双指针法能做到「无额外空间」求解。

3. 算法核心思想(等效路程法)

让两个指针分别从链表A、B的头节点出发,按以下规则移动:

  • 指针h1遍历完链表A(走到null)后,立刻转向链表B的头节点继续遍历;

  • 指针h2遍历完链表B(走到null)后,立刻转向链表A的头节点继续遍历;

  • 最终,两个指针会走 相同的总路程(n+m)

    • 若两链表相交:两指针会在相交节点相遇(h1 == h2);

    • 若不相交:两指针会同时走到null(h1 == h2 == null)。

原理:总路程相同 + 速度相同(每次走1步),必然同时到达终点(或相交点)。

二、代码逐行拆解(带注释)

Java 复制代码

三、分步演示(两种场景)

为了直观理解,分「两链表相交」和「两链表不相交」两种情况演示。

场景1:两链表相交(A长度=5,B长度=4,相交节点为3)

链表A:1→2→3→4→5(节点:A1、A2、A3、A4、A5)

链表B:6→7→3→4→5(节点:B1、B2、A3、A4、A5)

总路程:5+4=9步,两指针各走9步后相遇。

步数 h1(从A出发) h2(从B出发) 备注
0 A1(1) B1(6) 初始状态
1 A2(2) B2(7) 均未到终点,继续走
2 A3(3) A3(3) 此时h1=h2,相遇!循环结束
关键:h1走了2步到A3,h2走了2步到A3(总路程都是2,因两链表在A3相交,后续路程相同,提前相遇)。

场景2:两链表不相交(A长度=3,B长度=2)

链表A:1→2→3→null

链表B:4→5→null

总路程:3+2=5步,两指针各走5步后同时到null。

步数 h1(从A出发) h2(从B出发) 备注
0 A1(1) B1(4) 初始状态
1 A2(2) B2(5) 均未到终点
2 A3(3) null(B遍历完) h2转向A的头(A1)
3 null(A遍历完) A1(1) h1转向B的头(B1)
4 B1(4) A2(2) 继续走
5 B2(5) A3(3) 继续走
6 null(B遍历完) null(A遍历完) h1=h2=null,循环结束
关键:两指针都走了6步(总路程3+2=5?实际因null也算一步,最终同时到null,返回null正确)。

四、关键细节与避坑点

1. 为什么循环条件是h1 != h2

  • 若相交:h1和h2会在相交节点相等,循环终止,返回该节点;

  • 若不相交:h1和h2会同时走到null(h1h2null),循环终止,返回null(符合题目要求)。

2. 为什么指针走到null后要转向另一个链表的头?

核心是「凑齐相同总路程」。假设A长度n,B长度m:

  • h1的路径:A的n个节点 + B的m个节点(总n+m);

  • h2的路径:B的m个节点 + A的n个节点(总m+n);

总路程相同,速度相同(每次1步),必然同时到达终点(或相交点)。

3. 会不会陷入死循环?

不会!因为两指针的总路程是固定的(n+m),最多走n+m步后,必然会同时走到null(h1==h2),循环一定会终止。

4. 边界情况是否覆盖?

  • 其中一个链表为空(headAnull):h1初始为null,h2遍历完B后转向A(null),最终h1h2==null,返回null(正确);

  • 两个链表长度相同且相交:两指针同步走,直接在相交节点相遇;

  • 两个链表长度相同且不相交:同时走到null,返回null。

5. 为什么比哈希表方法更优?

哈希表方法(存A的所有节点,再遍历B查找)的时间复杂度是O(n+m),但空间复杂度是O(n)(需要存A的节点);而双指针法空间复杂度是O(1)(仅用两个指针),是最优解法。

五、总结

这段代码的核心是「等效路程法」:

  1. 双指针分别从两个链表头出发,遍历完一个链表后立刻转向另一个链表;

  2. 总路程相同 → 必然同时到达终点(或相交点);

  3. 循环终止时,h1和h2要么是相交节点,要么都是null,直接返回即可。

记住一句话:"你走我的路,我走你的路,我们终将相遇(或一起到尽头)",就能轻松理解并默写这段代码!如果还是不理解,建议动手画一画指针移动的每一步,可视化后会瞬间清晰。

相关推荐
arvin_xiaoting1 分钟前
OpenClaw学习总结_IV_认证与安全_3:Authorization与Policies详解
学习·安全
EnglishJun1 分钟前
ARM嵌入式学习(二十)--- 杂项设备、Platfrom总线和设备树源文件(dts)
学习
知识分享小能手2 分钟前
MongoDB入门学习教程,从入门到精通,MongoDB 安全完全指南(19)
学习·安全·mongodb
NULL指向我2 分钟前
信号处理学习笔记6:ADC采样线性处理实测拟合
人工智能·算法·机器学习
Lyyaoo.4 分钟前
【JAVA基础面经】线程安全的单例模式
java·安全·单例模式
汽车仪器仪表相关领域5 分钟前
NHXJ-02汽车悬架检验台 实操型实战手册
人工智能·功能测试·测试工具·算法·安全·单元测试·可用性测试
源码之屋6 分钟前
计算机毕业设计:Python天气数据采集与可视化分析平台 Django框架 线性回归 数据分析 大数据 机器学习 大模型 气象数据(建议收藏)✅
人工智能·python·深度学习·算法·django·线性回归·课程设计
我爱C编程7 分钟前
【3.2】FFT/IFFT变换的数学原理概述与MATLAB仿真
算法·matlab·fpga·fft·ifft
_李小白9 分钟前
【OSG学习笔记】Day 39: NodeCallback(帧回调机制)
java·笔记·学习
如来神掌十八式11 分钟前
设计模式之装饰器模式
java·设计模式