剑指offer系列——36.两个链表的第一个公共结点

Posted Shaw_喆宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer系列——36.两个链表的第一个公共结点相关的知识,希望对你有一定的参考价值。

Q:输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
T:这个题的意思是两个链表要么有公共结点,要么没有公共结点,不存在相交的情况。
A:
1.传统做法:长的先走,直到和短的相同长度,然后两个一起走,直至相等。

    ListNode *FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2) {
        if (pHead1 == nullptr || pHead2 == nullptr)
            return nullptr;
        ListNode *p1 = pHead1;
        ListNode *p2 = pHead2;
        int len1 = 0;
        int len2 = 0;
        while (p1) {
            p1 = p1->next;
            len1++;
        }
        while (p2) {
            p2 = p2->next;
            len2++;
        }
        int len3 = 0;
        p1 = pHead1;
        p2 = pHead2;
        if (len1 > len2) {
            len3 = len1 - len2;
            while (len3--)
                p1 = p1->next;
        } else if (len2 > len1) {
            len3 = len2 - len1;
            while (len3--)
                p2 = p2->next;
        }
        while (p1 != p2) {
            p1 = p1->next;
            p2 = p2->next;
        }
        return p1;
    }

2.这种方法代码更简单。
设第一条链表长度为\(a+n\),第二条链表长度为\(b+n\),且\(a>b\)\(p1\)\(p2\)同时向前走,\(p2\)走到结尾时,\(p1\)到达离结尾\(a-b\)处。\(p2\)跑到第一条链表开头,和\(p1\)同步前进。当\(p1\)走到结尾,跑到第二条链表开头,\(p2\)位于第一条链表\(a-b\)处,此时\(p1\)\(p2\)之后的链表长度相同,再可以按照上面的方法找相同结点。

public:
   ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
        ListNode* p1 = pHead1;
        ListNode* p2 = pHead2;
        while(p1 != p2) {
            if(p1 != NULL) p1 = p1->next;   
            if(p2 != NULL) p2 = p2->next;
            if(p1 != p2) {                  
                if(p1 == NULL) p1 = pHead2;
                if(p2 == NULL) p2 = pHead1;
            }
        }
        return p1;
}

以上是关于剑指offer系列——36.两个链表的第一个公共结点的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer36 两个链表的第一个公共子节点

剑指offer 36.时间空间效率的平衡两个链表的第一个公共结点

剑指offer两个链表的第一个公共结点

剑指 Offer 52. 两个链表的第一个公共节点

[8月4日]剑指 Offer 52. 两个链表的第一个公共节点

[8月4日]剑指 Offer 52. 两个链表的第一个公共节点