160. Intersection of Two Linked Lists
解题思路——拼接
题目要求我们找出两个链表 A、B 第一个相交的节点
第一个思路就是拼接,我们需要做三个操作:
- 把链表 A 的尾巴拼接上链表 B 得到链表 C
- 把链表 B 的尾巴拼接上链表 A 得到链表 D
- 从头到尾同时遍历链表 C 和 D,找到第一个相同的元素就是链表 A、B 第一个相交的节点
C++
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *p=headA;
ListNode *q=headB;
// flag 表示还没经过拼接,在遍历到链表尾的时候需要做一下拼接
bool flagA = true;
bool flagB = true;
while(p != q) {
if(p == nullptr && flagA) {
// 只需要拼接一次,不然如果没有交点的话会一直循环下去
flagA = false;
p = headB;
} else {
p = p->next;
}
if(q == nullptr && flagB) {
flagB = false;
q = headA;
} else {
q = q->next;
}
}
// 找到第一个相同的就是所求节点,如果没有就是 nullptr
return p;
}
};
解题思路——计算长度
这个思路也挺有意思的
我们知道两个有相交节点的相交部分长度是一样的,所以我们只需要计算两个链表的长度差 diff
然后将较长的那个链表先遍历 diff 个元素,这样一来两个链表剩下的长度就想等了
最后我们只需要同时遍历两个链表的剩余部分比较是否相同就好
C++
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *p=headA;
ListNode *q=headB;
int lenA = 0;
int lenB = 0;
// 计算两个链表长度
while(p != nullptr) {
lenA++;
p = p->next;
}
while(q != nullptr) {
lenB++;
q = q->next;
}
int diff;
// 把 p 指向比较长的链表
if(lenA > lenB) {
diff = lenA - lenB;
p = headA;
q = headB;
} else {
diff = lenB - lenA;
p = headB;
q = headA;
}
// 将比较长的那个链表先遍历一点
while(diff-- > 0) {
p = p->next;
}
// 这个时候两个链表剩余部分长度相同,直接一起遍历就好
while(p != q) {
p = p->next;
q = q->next;
}
return p;
}
};