问题描述
题目要求找到两个单链表相交的起始节点。如果两个链表没有交点,返回 NULL。假设链表没有环,且必须保持原始结构。
双指针相遇法思路
双指针相遇法的核心思想是通过让两个指针分别遍历两个链表,最终在相交点相遇。具体步骤如下:
初始化两个指针 pA 和 pB,分别指向链表 headA 和 headB 的头节点。
让 pA 和 pB 同时向前移动,每次移动一步。如果 pA 到达链表末尾(NULL),则将其重定向到 headB;如果 pB 到达链表末尾(NULL),则将其重定向到 headA。
当 pA 和 pB 相遇时,即为相交的起始节点。如果两个链表不相交,最终 pA 和 pB 会同时到达 NULL。
代码实现
c
// 链表节点定义(题目自带,必须写)
struct ListNode {
int val;
struct ListNode *next;
};
// 函数:输入两个链表头,返回相交节点
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
// 1. 定义两个指针,分别指向两条链表起点
struct ListNode *pA = headA;
struct ListNode *pB = headB;
// 2. 循环条件:两个指针不相等就持续移动
while (pA != pB) {
// pA没到末尾:向后走一步;到末尾就换到B链表开头
if (pA != NULL) {
pA = pA->next;
} else {
pA = headB;
}
// pB没到末尾:向后走一步;到末尾就换到A链表开头
if (pB != NULL) {
pB = pB->next;
} else {
pB = headA;
}
}
// 循环退出,两者相等,要么交点,要么NULL
return pA;
}
不适合采用递归法。
复杂度分析
时间复杂度为 O(m + n),其中 m 和 n 分别是链表 headA 和 headB 的长度。空间复杂度为 O(1),仅使用了两个指针变量。
关键点
双指针相遇法通过让两个指针分别遍历两个链表,确保它们最终走过相同的路径长度,从而在相交点相遇。这种方法避免了额外的空间消耗,同时保证了高效性。