1. 链表相交问题的本质理解
链表相交问题看似简单,实则蕴含着精妙的数据结构特性。要真正掌握这个问题,我们需要从最基础的链表结构说起。
单链表由一系列节点组成,每个节点包含两个部分:存储的数据(val)和指向下一个节点的指针(next)。这种结构决定了链表的一个重要特性——一旦两个链表在某节点相交,那么从这个节点开始,后续所有节点必然完全相同。这是因为每个节点只能有一个next指针,不可能出现分叉的情况。
关键理解:链表相交不是简单的数值相同,而是内存地址相同。两个链表可能在多个节点存储相同的数值,但只有内存地址相同的节点才是真正的相交点。
在实际编程面试中,面试官通常会给出这样的测试用例:
- 链表A:4→1→8→4→5
- 链表B:5→6→1→8→4→5
这里值为1的节点虽然数值相同,但内存地址不同;而值为8的节点才是真正的相交点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 传统解法及其局限性
2.1 哈希表法
最直观的解法是使用哈希表:
- 遍历链表A,将所有节点地址存入哈希表
- 遍历链表B,检查每个节点是否在哈希表中
- 第一个存在于哈希表中的节点就是相交点
这种方法时间复杂度O(m+n),空间复杂度O(m)或O(n),取决于哪个链表更长。虽然能解决问题,但需要额外的存储空间,不是最优解。
2.2 长度差法
另一种常见方法是:
- 分别遍历两个链表,计算长度
- 让长链表的指针先移动长度差步
- 然后两个指针同时移动,直到相遇
这种方法虽然空间复杂度降到了O(1),但仍需要两次完整遍历来计算长度,代码实现也相对复杂。
3. 双指针法的精妙之处
3.1 核心思路
双指针法之所以高效,是因为它利用了数学上的对称性。让我们用生活中的例子来理解:
想象两个人在不同的跑道上跑步:
- 跑道A长度a+c(a段独有,c段共享)
- 跑道B长度b+c(b段独有,c段共享)
如果两人分别从各自起点出发,速度相同:
- 跑完自己的跑道后,立即换到对方的起点
- 这样两人跑的总距离都是a+b+c
- 必定会在共享段的起点相遇
3.2 数学证明
设:
- 链表A独有部分长度a
- 链表B独有部分长度b
- 共享部分长度c
指针pA的路径:a→c→b→c
指针pB的路径:b→c→a→c
可以看到,在走完a+
