跳到主要内容

相交链表

题解

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
auto ptrA = headA;
auto ptrB = headB;
int lenA = 0;
int lenB = 0;
// 首先统计链表长度,并找到尾节点
while (ptrA->next != nullptr) {
ptrA = ptrA->next;
lenA++;
}
while (ptrB->next != nullptr) {
ptrB = ptrB->next;
lenB++;
}
// 如果尾节点不相同代表没有相交的地方
if (ptrA != ptrB) {
return nullptr;
}

// 如果长度不相同,就手动调整一个链表
if (lenA > lenB) {
int t = lenA - lenB;
while (t--) {
headA = headA->next;
}
} else {
int t = lenB - lenA;
while (t--) {
headB = headB->next;
}
}

// 同步前进,找相交节点
while (headA != headB) {
headA = headA->next;
headB = headB->next;
}
return headA;
}
};

官方题解一是使用 hashset, 记录链表 A 的每一个节点,然后遍历链表 B。

官方题解二比较有意思,使用双指针。

class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == nullptr ? headB : pA->next;
pB = pB == nullptr ? headA : pB->next;
}
return pA;
}
};

官方证明:

alt text

评论区给出的思路也很有意思,题解二相当于将每个链表的长度变成两个链表长度之和。最多移动 m+n 次。

alt text