思路: 这道题首先先到的就是暴力解法,直接两个循环,寻找链表A与链表B相等的结点,即地址是否相等,代码如下:
//暴力解法
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* cura = headA;
ListNode* curb = headB;
while(cura != nullptr){
curb = headB;
while(curb != nullptr){
if(cura == curb) return cura;
curb = curb->next;
}
cura = cura->next;
}
return NULL;
}
};
在题解中看到一个很巧妙的方法:
// 浪漫相遇解法
// 思路: A长度为 a, B长度为b, 假设存在交叉点,此时 A到交叉点距离为 c, 而B到交叉点距离为d
// 后续交叉后长度是一样的,那么就是 a-c = b-d -> a+d = b+c
// 这里意味着只要分别让A和B额外多走一遍B和A,那么必然会走到交叉,注意这里边缘情况是,大家都走到null依然没交叉,那么正好返回null即可
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* a = headA;
ListNode* b = headB;
while (a != b)
{
a = a != nullptr ? a->next : headB;
b = b != nullptr ? b->next : headA;
}
return a;
}
};
// 作者:ffreturn
// 链接:https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/solutions/621146/cji-hu-shuang-bai-de-dan-ci-bian-li-jie-ups5w/
// 来源:力扣(LeetCode)
下面是随想录的解法,也是比较正常的解法,先让长链表和短链表对齐,然后寻找相等结点:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0, lenB = 0;
while (curA != NULL) { // 求链表A的长度
lenA++;
curA = curA->next;
}
while (curB != NULL) { // 求链表B的长度
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
// 让curA为最长链表的头,lenA为其长度
if (lenB > lenA) {
swap (lenA, lenB);
swap (curA, curB);
}
// 求长度差
int gap = lenA - lenB;
// 让curA和curB在同一起点上(末尾位置对齐)
while (gap--) {
curA = curA->next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while (curA != NULL) {
if (curA == curB) {
return curA;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};