链表—相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

这道题的核心是找到两个单链表的相交起始节点,要求O(1)空间复杂度,O(m+n)时间复杂度,且不能修改原链表结构。

最优解题私立:双指针法(浪漫相遇法)
核心逻辑:让两个指针遍历完自己的链表后,再去遍历对方的链表,最终一定会在相交节点相遇,或者同时走到null(无相交)。

  1. 用指针pA指向headA,指针pB指向headB;
  2. 两个指针同时向后移动
  3. 若pA走到末尾,就跳到headB继续走;若pB走到末尾,就跳到headA继续走;
  4. 当pA==pB时,就是相交节点(或NULL)。

原理:两个指针走过的总长度相同(lenA + lenB),必然会在交点相遇。

完整代码实现如下
#include
using namespace std;

// 链表节点定义(题目默认提供)
struct ListNode {

int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};

class Solution {

public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {

// 定义两个指针,分别指向两个链表的头节点
ListNode *pA = headA;
ListNode *pB = headB;

// 指针不相等时循环遍历
while (pA != pB) {
// pA 走到末尾就切换到 B 链表,否则向后走
pA = (pA == nullptr) ? headB : pA->next;
// pB 走到末尾就切换到 A 链表,否则向后走
pB = (pB == nullptr) ? headA : pB->next;
}

// 最终 pA 和 pB 相等:要么是相交节点,要么是 nullptr
return pA;
}
};

// 测试代码
int main() {

// 创建链表 A: 4 -> 1 -> 8 -> 4 -> 5
ListNode* a1 = new ListNode(4);
ListNode* a2 = new ListNode(1);
// 相交节点
ListNode* c1 = new ListNode(8);
ListNode* c2 = new ListNode(4);
ListNode* c3 = new ListNode(5);
a1->next = a2;
a2->next = c1;
c1->next = c2;
c2->next = c3;

// 创建链表 B: 5 -> 6 -> 1 -> 8 -> 4 -> 5
ListNode* b1 = new ListNode(5);
ListNode* b2 = new ListNode(6);
ListNode* b3 = new ListNode(1);
b1->next = b2;
b2->next = b3;
b3->next = c1;

Solution sol;
ListNode* res = sol.getIntersectionNode(a1, b1);
if (res) {
cout << "相交节点的值为:" << res->val << endl; // 输出 8
} else {
cout << "无相交节点" << endl;
}

return 0;
}

代码核心解释

1.双指针初始化:pA 指向链表 A 头,pB 指向链表 B 头;
2.循环逻辑:

  • 指针走到链表末尾,就切换到另一个链表的头部继续遍历;
  • 没走到末尾就正常向后移动;
    3.终止条件:pA == pB,此时返回的就是相交节点(无相交则返回 nullptr)。

复杂度分析

  • 时间复杂度:O (m + n),m、n 分别为两个链表的长度,每个指针最多遍历两个链表各一次;
  • 空间复杂度:O (1),仅使用两个指针,无额外空间开销。

之所以能相遇在交点,
不是因为值相等
不是因为路径对称,
而是因为:
相交之后两条链表完全重合,长度完全一样!

如果相交之后节点不一样(只是值一样):
——> 这个算法直接失效。

为什么这个前提决定了算法能成立?

设:

  • A 前面独有的长度:x
  • B 前面独有的长度:y
  • 公共部分长度:z

那么:

  • A 总长度:x + z
  • B 总长度:y + z

重点来了:
公共部分 z 是完全一样的!

当两个指针:

  • pA 走:A + B = x+z + y
  • pB 走:B + A = y+z + x

路程完全相等:
x+z+y = y+z+x

而且:
前面 x+y 是各自独有的部分,
最后同时进入公共部分 z!

所以它们必然同时到达 c1。

posted @ 2026-04-01 11:51  ZealousMclaren  阅读(19)  评论(0)    收藏  举报