题目描述
给你两个单链表的头节点 headA 和 headB,请你找160出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null。
注意:函数返回结果后,链表必须保持其原始结构。
问题分析
链表相交定义
链表相交指的是两个链表在某个节点后面共享相同的节点序列,是节点引用相同,而不是节点值相同。
链表A: [4] -> [1] ----\ \ [8] -> [4] -> [5] -> NULL / 链表B: [5] -> [0] -> [1] ----/ 相交起始节点:节点8(注意是节点引用,不是值)
解题思路
方法一:双指针法(优选)
算法思路
核心思想:让两个指针走过的路径长度相同
-
指针pA从headA开始,指针pB从headB开始
-
当pA到达末尾时,跳到headB继续
-
当pB到达末尾时,跳到headA继续
-
如果有相交点,两指针必定会在相交点相遇
数学推导
设链表A长度为a,链表B长度为b,相交部分长度为c 链表A:a1 -> a2 -> ... -> c1 -> c2 -> ... -> NULL 链表B:b1 -> b2 -> ... -> c1 -> c2 -> ... -> NULL 指针pA路径:a1->...->c1->...->NULL->b1->...->c1 (总长度: a + b) 指针pB路径:b1->...->c1->...->NULL->a1->...->c1 (总长度: b + a) 两个指针走过相同的路径长度时,会在相交点c1相遇
代码实现
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode *pA = headA;
ListNode *pB = headB;
// 两个指针一直移动,直到相遇或者都为null
while (pA != pB) {
// pA达到末尾时跳转到headB,否则移动到下一节点
pA = (pA == nullptr)? headB : pA->next;
// pB达到末尾时跳转到head,否则移动到下一个节点
pB = (pB == nullptr)? headA : pB->next;
}
// 相交点或为null
return pA;
}
};
方法二:哈希表法
算法思路
-
遍历链表A,将所有节点存入哈希表
-
遍历链表B,检查每个节点是否在哈希表中
-
第一个在哈希表中的节点就是相交起始节点
算法流程
步骤1:遍历链表A,存入哈希表
链表A: [4] -> [1] -> [8] -> [4] -> [5] -> NULL
↓ ↓ ↓ ↓ ↓
哈希表: {4, 1, 8, 4, 5}
步骤2:遍历链表B,查找相交点
链表B: [5] -> [0] -> [1] -> [8] -> [4] -> [5] -> NULL
↓ ↓ ↓ ↓
不在 不在 不在 找到!
↑
相交起始节点
代码实现
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
// 方法一:哈希表法
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
unordered_set<ListNode*> visited;
// 遍历链表A,将所有节点存入哈希表
ListNode* currA = headA;
while (currA != nullptr) {
visited.insert(currA);
currA = currA->next;
}
// 遍历链表B,查找第一个在哈希表中的节点
ListNode* currB = headB;
while (currB != nullptr) {
if (visited.find(currB) != visited.end()) {
return currB; // 找到相交起始节点
}
currB = currB->next;
}
return nullptr; // 没有相交点
}
};
复杂度分析
| 方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 哈希表法 | O(m+n) | O(m) | 思路直观 | 需要额外空间 |
| 双指针法 | O(m+n) | O(1) | 空间最优,代码简洁 | 需要理解数学原理 |
其中 m、n 分别是两个链表的长度。
3744

被折叠的 条评论
为什么被折叠?



