LeetCode | 相交链表

793 字
4 分钟
LeetCode | 相交链表

分类:链表 / 哈希集合 / 双指针

题目#

给定两个单链表的头节点 headAheadB,找出两个链表相交的起始节点。如果两个链表不相交,返回 None

这里的“相交”不是节点值相等,而是两个链表从某个节点开始共用同一段节点。

平台会根据 intersectVallistAlistBskipAskipB 构造链表,但这些不是函数的直接输入。函数真正接收的是两个头节点 headAheadB

要求函数返回后,两个链表仍然保持原来的结构;题目保证整个链式结构中没有环。

示例:

相交链表示例 1
相交链表示例 1

intersectVal = 8
listA = [4,1,8,4,5]
listB = [5,6,1,8,4,5]
skipA = 2
skipB = 3
输出:相交节点 8

其余例子略

讲解#

这道题要找的是“同一个节点对象”,不是值相同的节点。

哈希集合#

先走一遍链表 A,把 A 里面出现过的节点都放进一个集合;再走一遍链表 B,第一个已经在集合里的节点,就是相交的起始节点。

set() 是 Python 里的集合。它只关心“某个东西在不在里面”,不保存下标,也不保存对应关系。这里 visited = set() 表示创建一个空集合,visited.add(cur) 表示把当前节点放进去,cur in visited 表示判断当前节点以前是否出现过。

它和两数之和里的哈希表很像,都是利用哈希让查找平均为 O(1)。区别是:两数之和用字典保存“数字 -> 下标”,这里用集合只保存“这个节点出现过”。

长度差对齐#

先分别算出两条链表的长度 lenAlenB。如果长链表比短链表多 s 个节点,就先让长链表走 s 步。这样两个指针到尾部的距离就一样了。

之后两个指针一起往后走:如果它们指向同一个节点,这个节点就是相交的起始节点;如果一直没有相同节点,最后会同时走到 None,说明不相交。

复杂度#

  • 哈希集合法:时间复杂度 O(m + n),空间复杂度 O(m)
  • 长度差对齐法:时间复杂度 O(m + n),空间复杂度 O(1)

代码#

哈希集合法#

源码#

class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
_hash =set();
pointerA = headA
while (pointerA):
_hash.add(pointerA)
pointerA = pointerA.next
pointerB = headB
while (pointerB):
if pointerB in _hash:
return pointerB
pointerB = pointerB.next
return None

长度差对齐法#

源码#

class Solution:
def getIntersectionNode(self, headA: "ListNode", headB: "ListNode") -> "ListNode":
lenA = self.getLength(headA)
lenB = self.getLength(headB)
if lenA >= lenB:
long, short = headA, headB
else:
long, short = headB, headA
for _ in range(abs(lenA - lenB)):
long = long.next
while long != short:
long = long.next
short = short.next
return long
def getLength(self, head: "ListNode") -> int:
length = 0
while head:
length += 1
head = head.next
return length

测试#

class ListNode:
def __init__(self, x):
self.val = x
self.next = None
sol = Solution()
common = ListNode(8)
common.next = ListNode(4)
common.next.next = ListNode(5)
headA = ListNode(4)
headA.next = ListNode(1)
headA.next.next = common
headB = ListNode(5)
headB.next = ListNode(6)
headB.next.next = ListNode(1)
headB.next.next.next = common
assert sol.getIntersectionNode(headA, headB) is common
headA = ListNode(2)
headA.next = ListNode(6)
headA.next.next = ListNode(4)
headB = ListNode(1)
headB.next = ListNode(5)
assert sol.getIntersectionNode(headA, headB) is None
assert sol.getIntersectionNode(None, ListNode(1)) is None
print("PASS")

参考资料#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

LeetCode | 相交链表
https://leetcode.cn/problems/intersection-of-two-linked-lists/
作者
平昊阳
发布于
2026-07-31
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
平昊阳
乘长风,破巨浪, 展鸿图于未央!
--
总访问量
--
访客数
公告
欢迎来到我的个人博客!欢迎关注交流吖!
更多相关公告,见
社交-留言」。
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
站点统计
文章
66
分类
16
标签
93
总字数
477,284
运行时长
0
最后活动
0 天前

文章目录