• 《剑指offer》第五十二题:两个链表的第一个公共结点


    // 面试题52:两个链表的第一个公共结点
    // 题目:输入两个链表,找出它们的第一个公共结点。
    
    #include <cstdio>
    #include "List.h"
    
    unsigned int GetListLength(ListNode* pHead);
    
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2)
    {
        //获取两个链表长度
        unsigned int length1 = GetListLength(pHead1);
        unsigned int length2 = GetListLength(pHead2);
        ListNode* pHeadLong = pHead1;
        ListNode* pHeadShort = pHead2;
        int lengthDif = length1 - length2;  //默认链表1长
    
        if (length1 < length2)  //如果链表2更长
        {
            pHeadLong = pHead2;
            pHeadShort = pHead1;
            lengthDif = length2 - length1;
        }
    
        //长的链表先走一步
        for (int i = 0; i < lengthDif; ++i)
            pHeadLong = pHeadLong->m_pNext;
    
        //然后两个链表一起走找公共节点
        while ((pHeadLong != nullptr)
            && (pHeadShort != nullptr)
            && (pHeadLong != pHeadShort))  //value和next都相同
        {
            pHeadLong = pHeadLong->m_pNext;
            pHeadShort = pHeadShort->m_pNext;
        }
    
        return pHeadLong;  //第一个公共结点
    }
    
    unsigned int GetListLength(ListNode* pHead)  //遍历链表获得长度
    {
        unsigned int length = 0;
        ListNode* pNode = pHead;
        while (pNode != nullptr)
        {
            ++length;
            pNode = pNode->m_pNext;
        }
        return length;
    }
    // ====================测试代码====================
    void DestroyNode(ListNode* pNode);
    
    void Test(char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected)
    {
        if(testName != nullptr)
            printf("%s begins: ", testName);
    
        ListNode* pResult = FindFirstCommonNode(pHead1, pHead2);
        if(pResult == pExpected)
            printf("Passed.
    ");
        else
            printf("Failed.
    ");
    }
    
    // 第一个公共结点在链表中间
    // 1 - 2 - 3 
    //            6 - 7
    //     4 - 5 /
    void Test1()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
        ListNode* pNode6 = CreateListNode(6);
        ListNode* pNode7 = CreateListNode(7);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode6);
        ConnectListNodes(pNode4, pNode5);
        ConnectListNodes(pNode5, pNode6);
        ConnectListNodes(pNode6, pNode7);
    
        Test("Test1", pNode1, pNode4, pNode6);
    
        DestroyNode(pNode1);
        DestroyNode(pNode2);
        DestroyNode(pNode3);
        DestroyNode(pNode4);
        DestroyNode(pNode5);
        DestroyNode(pNode6);
        DestroyNode(pNode7);
    }
    
    // 没有公共结点
    // 1 - 2 - 3 - 4
    //            
    // 5 - 6 - 7
    void Test2()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
        ListNode* pNode6 = CreateListNode(6);
        ListNode* pNode7 = CreateListNode(7);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode4);
        ConnectListNodes(pNode5, pNode6);
        ConnectListNodes(pNode6, pNode7);
    
        Test("Test2", pNode1, pNode5, nullptr);
    
        DestroyList(pNode1);
        DestroyList(pNode5);
    }
    
    // 公共结点是最后一个结点
    // 1 - 2 - 3 - 4 
    //                7
    //         5 - 6 /
    void Test3()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
        ListNode* pNode6 = CreateListNode(6);
        ListNode* pNode7 = CreateListNode(7);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode4);
        ConnectListNodes(pNode4, pNode7);
        ConnectListNodes(pNode5, pNode6);
        ConnectListNodes(pNode6, pNode7);
    
        Test("Test3", pNode1, pNode5, pNode7);
    
        DestroyNode(pNode1);
        DestroyNode(pNode2);
        DestroyNode(pNode3);
        DestroyNode(pNode4);
        DestroyNode(pNode5);
        DestroyNode(pNode6);
        DestroyNode(pNode7);
    }
    
    // 公共结点是第一个结点
    // 1 - 2 - 3 - 4 - 5
    // 两个链表完全重合   
    void Test4()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode4);
        ConnectListNodes(pNode4, pNode5);
    
        Test("Test4", pNode1, pNode1, pNode1);
    
        DestroyList(pNode1);
    }
    
    // 输入的两个链表有一个空链表
    void Test5()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode4);
        ConnectListNodes(pNode4, pNode5);
    
        Test("Test5", nullptr, pNode1, nullptr);
    
        DestroyList(pNode1);
    }
    
    // 输入的两个链表有一个空链表
    void Test6()
    {
        Test("Test6", nullptr, nullptr, nullptr);
    }
    
    void DestroyNode(ListNode* pNode)
    {
        delete pNode;
        pNode = nullptr;
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
    
        return 0;
    }
    测试代码

    分析:思路很重要。

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
    };*/
    class Solution {
    public:
        ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
            
            unsigned int nLength1 = GetListLength(pHead1);
            unsigned int nLength2 = GetListLength(pHead2);
            int nLengthDif = nLength1 - nLength2;
            ListNode* pListHeadLong = pHead1;
            ListNode* pListHeadShort = pHead2;
            
            if (nLength1 < nLength2)
            {
                int nLengthDif = nLength2 - nLength1;
                ListNode* pListHeadLong = pHead2;
                ListNode* pListHeadShort = pHead1;
            }
            
            for (int i = 0; i < nLengthDif; ++i)
                pListHeadLong = pListHeadLong->next;
            
            while ((pListHeadLong != nullptr)
                   && (pListHeadShort != nullptr)
                   && (pListHeadLong != pListHeadShort))
            {
                pListHeadLong = pListHeadLong->next;
                pListHeadShort = pListHeadShort->next;
            }
            return pListHeadLong;
        }
        
        unsigned int GetListLength(ListNode* pHead)
        {
            unsigned int length = 0;
            ListNode* pNode = pHead;
            while (pNode != nullptr)
            {
                ++length;
                pNode = pNode->next;
            }
            return length;
        }
    };
    牛客网提交代码
  • 相关阅读:
    课程作业02
    课后作业01
    大道至简第一章伪代码
    《大道至简》读后感
    Codeforces 959 F. Mahmoud and Ehab and yet another xor task
    Codeforces 992 E. Nastya and King-Shamans
    Codeforces 835 F. Roads in the Kingdom
    Codeforces 980 D. Perfect Groups
    洛谷 P4315 月下“毛景树”
    JDOJ 1234: VIJOS-P1052 高斯消元
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12644124.html
Copyright © 2020-2023  润新知