音乐
音乐
暂未播放
0:00/0:00
暂无歌词
LeetCode | 相交链表
793 字
4 分钟
LeetCode | 相交链表
分类:链表 / 哈希集合 / 双指针
题目#
给定两个单链表的头节点 headA 和 headB,找出两个链表相交的起始节点。如果两个链表不相交,返回 None。
这里的“相交”不是节点值相等,而是两个链表从某个节点开始共用同一段节点。
平台会根据 intersectVal、listA、listB、skipA、skipB 构造链表,但这些不是函数的直接输入。函数真正接收的是两个头节点 headA 和 headB。
要求函数返回后,两个链表仍然保持原来的结构;题目保证整个链式结构中没有环。
示例:

1intersectVal = 82listA = [4,1,8,4,5]3listB = [5,6,1,8,4,5]4skipA = 25skipB = 36输出:相交节点 8其余例子略
讲解#
这道题要找的是“同一个节点对象”,不是值相同的节点。
哈希集合#
先走一遍链表 A,把 A 里面出现过的节点都放进一个集合;再走一遍链表 B,第一个已经在集合里的节点,就是相交的起始节点。
set() 是 Python 里的集合。它只关心“某个东西在不在里面”,不保存下标,也不保存对应关系。这里 visited = set() 表示创建一个空集合,visited.add(cur) 表示把当前节点放进去,cur in visited 表示判断当前节点以前是否出现过。
它和两数之和里的哈希表很像,都是利用哈希让查找平均为 O(1)。区别是:两数之和用字典保存“数字 -> 下标”,这里用集合只保存“这个节点出现过”。
长度差对齐#
先分别算出两条链表的长度 lenA 和 lenB。如果长链表比短链表多 s 个节点,就先让长链表走 s 步。这样两个指针到尾部的距离就一样了。
之后两个指针一起往后走:如果它们指向同一个节点,这个节点就是相交的起始节点;如果一直没有相同节点,最后会同时走到 None,说明不相交。
复杂度#
- 哈希集合法:时间复杂度
O(m + n),空间复杂度O(m) - 长度差对齐法:时间复杂度
O(m + n),空间复杂度O(1)
代码#
哈希集合法#
源码#
1class Solution:2 def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:3 _hash =set();4
5 pointerA = headA6 while (pointerA):7 _hash.add(pointerA)8 pointerA = pointerA.next9
10 pointerB = headB11 while (pointerB):12 if pointerB in _hash:13 return pointerB14 pointerB = pointerB.next15
16 return None长度差对齐法#
源码#
1class Solution:2 def getIntersectionNode(self, headA: "ListNode", headB: "ListNode") -> "ListNode":3 lenA = self.getLength(headA)4 lenB = self.getLength(headB)5
6 if lenA >= lenB:7 long, short = headA, headB8 else:9 long, short = headB, headA10
11 for _ in range(abs(lenA - lenB)):12 long = long.next13
14 while long != short:15 long = long.next16 short = short.next17
18 return long19
20 def getLength(self, head: "ListNode") -> int:21 length = 022 while head:23 length += 124 head = head.next25 return length测试#
1class ListNode:2 def __init__(self, x):3 self.val = x4 self.next = None5
6
7sol = Solution()8
9common = ListNode(8)10common.next = ListNode(4)11common.next.next = ListNode(5)12
13headA = ListNode(4)14headA.next = ListNode(1)15headA.next.next = common16
17headB = ListNode(5)18headB.next = ListNode(6)19headB.next.next = ListNode(1)20headB.next.next.next = common21
22assert sol.getIntersectionNode(headA, headB) is common23
24headA = ListNode(2)25headA.next = ListNode(6)26headA.next.next = ListNode(4)27
28headB = ListNode(1)29headB.next = ListNode(5)30
31assert sol.getIntersectionNode(headA, headB) is None32assert sol.getIntersectionNode(None, ListNode(1)) is None33
34print("PASS")参考资料#
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
最后更新于 2026-07-31
部分内容可能已过时
相关文章智能推荐
1
LeetCode | 反转链表
LeetCodeLeetCode 反转链表题解:使用迭代法逐个翻转节点指向,时间复杂度 O(n),空间复杂度 O(1)。
2
LeetCode | 合并两个有序链表
LeetCodeLeetCode 合并两个有序链表题解:双指针遍历比较节点值,dummy 虚拟头节点串联结果链表。
3
LeetCode | 移动零
LeetCodeLeetCode 移动零题解:使用双指针原地移动零,同时保持非零元素相对顺序。
4
LeetCode | 两数相加
LeetCodeLeetCode 两数相加题解:模拟竖式逐位相加,dummy 虚拟头节点串联结果链表,维护 carry 进位。
5
LeetCode | 双指针
LeetCode整理 LeetCode 双指针题目的核心思路:用两个指针描述位置或范围,并按规则移动,涵盖移动零、盛水容器、三数之和、接雨水、最长回文子串。
随机文章随机推荐
暂无随机文章
评论区
分享你的想法,与大家交流讨论
--
总访问量
--
访客数
公告
音乐
音乐
暂未播放
0:00/0:00
暂无歌词
站点统计
文章
66
分类
16
标签
93
总字数
477,284
运行时长
0 天
最后活动
0 天前
最新动态



