zoukankan      html  css  js  c++  java
  • 剑指offer36:两个链表的第一个公共结点

    1 题目描述

      输入两个链表,找出它们的第一个公共结点。

    2 思路和方法

      方法一:

      用两个指针同时从两个链表的表头开始走,当走到自己的链表结尾的时候开始从另一个链表的表头开始向后走。终止条件就是两个指针第一次相遇。此时指针位置即为所求。(两个链表的节点和是一定的,所以两个指针一定可以同时遍历完两条链表,即在最后时刻两个指针一定是重合的)

      方法2:

      先数出两条链表的长度,得到长度差d,先将长链表从头结点往后走d步,之后第二个链表从头开始,两个链表一起一步一步走,直到两个链表的节点第一次相等为止,此时指针位置即为所求。

    3 C++核心代码

    1 ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {
    2         ListNode *p1 = pHead1;
    3         ListNode *p2 = pHead2;
    4         while(p1!=p2){
    5             p1 = (p1==NULL ? pHead2 : p1->next);
    6             p2 = (p2==NULL ? pHead1 : p2->next);
    7         }
    8         return p1;
    9     }
    View Code
     1     ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
     2         ListNode *p1=pHead1;
     3         ListNode *p2=pHead2;
     4         int len1=0,len2=0,diff=0;
     5         while(p1!=NULL){
     6             p1=p1->next;
     7             len1++;
     8         }
     9         while(p2!=NULL){
    10             p2=p2->next;
    11             len2++;
    12         }
    13         if(len1>len2){
    14             diff=len1-len2;
    15             p1=pHead1;
    16             p2=pHead2;
    17         }
    18         else{
    19             diff=len2-len1;
    20             p1=pHead2;
    21             p2=pHead1;
    22         }
    23         for(int i=0;i<diff;i++){
    24             p1=p1->next;
    25         }
    26         while(p1!=NULL && p2!=NULL){
    27             if(p1==p2)
    28                 break;
    29             p1=p1->next;
    30             p2=p2->next;
    31         }
    32         return p1;
    33     }
    View Code

    4 C++完整代码

      1 #include<iostream>
      2 using namespace std;
      3  
      4 struct ListNode
      5 {
      6     int m_nValue;
      7     ListNode* m_pNext;
      8 };
      9  
     10 //创建链表节点
     11 ListNode* CreateListNode(int value)
     12 {
     13     ListNode* pNode = new ListNode();
     14     pNode->m_nValue = value;
     15     pNode->m_pNext = NULL;
     16  
     17     return pNode;
     18 }
     19  
     20  
     21 //连接链表节点
     22 void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
     23 {
     24     if (pCurrent == NULL)
     25     {
     26         //exit(1),非正常运行导致退出程序;exit(0),正常运行并退出程序
     27         cout << "Error to connect two nodes." << endl;
     28         exit(1);
     29     }
     30  
     31     pCurrent->m_pNext = pNext;
     32 }
     33  
     34  
     35 //销毁链表
     36 void DestroyList(ListNode* pHead)
     37 {
     38     ListNode* pNode = pHead;
     39  
     40     while (pNode!=NULL)
     41     {
     42         pHead = pHead->m_pNext;
     43         delete pNode;
     44         pNode = pHead;
     45     }
     46 }
     47  
     48 //销毁节点
     49 void DestroyNode(ListNode* pNode)
     50 {
     51     delete pNode;
     52     pNode = NULL;
     53 }
     54  
     55 //求链表的长度
     56 unsigned int GetListLength(ListNode* pHead)
     57 {
     58     unsigned int nLength = 0;
     59     ListNode* pNode = pHead;
     60  
     61     while (pNode!=NULL)
     62     {
     63         nLength++;
     64         pNode = pNode->m_pNext;
     65     }
     66  
     67     return nLength;
     68 }
     69  
     70 //找第一个公共节点
     71 ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)
     72 {
     73     //求两个链表的长度
     74     unsigned int nLength1 = GetListLength(pHead1);
     75     unsigned int nLength2 = GetListLength(pHead2);
     76     //两个链表的长度差
     77     int nLengthDif = nLength1 - nLength2;
     78     ListNode* pListHeadLong = pHead1;
     79     ListNode* pListHeadShort= pHead2;
     80     if (nLength2 > nLength1)
     81     {
     82         pListHeadLong = pHead2;
     83         pListHeadShort = pHead1;
     84         nLengthDif = nLength2 - nLength1;
     85     }
     86  
     87     // 先在长链表上走几步,再同时在两个链表上遍历
     88     for (int i = 0; i < nLengthDif; i++)
     89     {
     90         pListHeadLong = pListHeadLong->m_pNext;
     91     }
     92  
     93     while ((pListHeadLong!=NULL)&& (pListHeadShort != NULL)&&(pListHeadLong != pListHeadShort))
     94     {
     95         pListHeadLong = pListHeadLong->m_pNext;
     96         pListHeadShort = pListHeadShort->m_pNext;
     97     }
     98  
     99     //得到第一个公共节点
    100     ListNode* pFisrtCommonNode = pListHeadLong;
    101     //ListNode* pFisrtCommonNode = pListHeadShort;也可以
    102  
    103     return pFisrtCommonNode;
    104 }
    105  
    106  
    107 // ====================测试代码====================
    108 void Test(char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected)
    109 {
    110     if (testName != NULL)
    111     {
    112         cout << testName << "  begins: ";
    113     }
    114  
    115     ListNode* pResult = FindFirstCommonNode(pHead1, pHead2);
    116     if (pResult == pExpected)
    117     {
    118         cout << "Succeed!" << endl;
    119     }
    120     else
    121     {
    122         cout << "Failed!" << endl;
    123     }
    124 }
    125  
    126  
    127 // 第一个公共结点在链表中间
    128 // 1 - 2 - 3 
    129 //                6 - 7
    130 //      4 - 5 /
    131 void Test1()
    132 {
    133     ListNode* pNode1 = CreateListNode(1);
    134     ListNode* pNode2 = CreateListNode(2);
    135     ListNode* pNode3 = CreateListNode(3);
    136     ListNode* pNode4 = CreateListNode(4);
    137     ListNode* pNode5 = CreateListNode(5);
    138     ListNode* pNode6 = CreateListNode(6);
    139     ListNode* pNode7 = CreateListNode(7);
    140  
    141     ConnectListNodes(pNode1, pNode2);
    142     ConnectListNodes(pNode2, pNode3);
    143     ConnectListNodes(pNode3, pNode6);
    144     ConnectListNodes(pNode4, pNode5);
    145     ConnectListNodes(pNode5, pNode6);
    146     ConnectListNodes(pNode6, pNode7);
    147  
    148     Test("Test1", pNode1, pNode4, pNode6);
    149  
    150     DestroyNode(pNode1);
    151     DestroyNode(pNode2);
    152     DestroyNode(pNode3);
    153     DestroyNode(pNode4);
    154     DestroyNode(pNode5);
    155     DestroyNode(pNode6);
    156     DestroyNode(pNode7);
    157 }
    158  
    159 // 没有公共结点
    160 // 1 - 2 - 3 - 4
    161 //            
    162 // 5 - 6 - 7
    163 void Test2()
    164 {
    165     ListNode* pNode1 = CreateListNode(1);
    166     ListNode* pNode2 = CreateListNode(2);
    167     ListNode* pNode3 = CreateListNode(3);
    168     ListNode* pNode4 = CreateListNode(4);
    169     ListNode* pNode5 = CreateListNode(5);
    170     ListNode* pNode6 = CreateListNode(6);
    171     ListNode* pNode7 = CreateListNode(7);
    172  
    173     ConnectListNodes(pNode1, pNode2);
    174     ConnectListNodes(pNode2, pNode3);
    175     ConnectListNodes(pNode3, pNode4);
    176     ConnectListNodes(pNode5, pNode6);
    177     ConnectListNodes(pNode6, pNode7);
    178  
    179     Test("Test2", pNode1, pNode5, NULL);
    180  
    181     DestroyList(pNode1);
    182     DestroyList(pNode5);
    183 }
    184  
    185 // 公共结点是最后一个结点
    186 // 1 - 2 - 3 - 4 
    187 //                      7
    188 //           5 - 6 /
    189 void Test3()
    190 {
    191     ListNode* pNode1 = CreateListNode(1);
    192     ListNode* pNode2 = CreateListNode(2);
    193     ListNode* pNode3 = CreateListNode(3);
    194     ListNode* pNode4 = CreateListNode(4);
    195     ListNode* pNode5 = CreateListNode(5);
    196     ListNode* pNode6 = CreateListNode(6);
    197     ListNode* pNode7 = CreateListNode(7);
    198  
    199     ConnectListNodes(pNode1, pNode2);
    200     ConnectListNodes(pNode2, pNode3);
    201     ConnectListNodes(pNode3, pNode4);
    202     ConnectListNodes(pNode4, pNode7);
    203     ConnectListNodes(pNode5, pNode6);
    204     ConnectListNodes(pNode6, pNode7);
    205  
    206     Test("Test3", pNode1, pNode5, pNode7);
    207  
    208     DestroyNode(pNode1);
    209     DestroyNode(pNode2);
    210     DestroyNode(pNode3);
    211     DestroyNode(pNode4);
    212     DestroyNode(pNode5);
    213     DestroyNode(pNode6);
    214     DestroyNode(pNode7);
    215 }
    216  
    217 // 公共结点是第一个结点
    218 // 1 - 2 - 3 - 4 - 5
    219 // 两个链表完全重合   
    220 void Test4()
    221 {
    222     ListNode* pNode1 = CreateListNode(1);
    223     ListNode* pNode2 = CreateListNode(2);
    224     ListNode* pNode3 = CreateListNode(3);
    225     ListNode* pNode4 = CreateListNode(4);
    226     ListNode* pNode5 = CreateListNode(5);
    227  
    228     ConnectListNodes(pNode1, pNode2);
    229     ConnectListNodes(pNode2, pNode3);
    230     ConnectListNodes(pNode3, pNode4);
    231     ConnectListNodes(pNode4, pNode5);
    232  
    233     Test("Test4", pNode1, pNode1, pNode1);
    234  
    235     DestroyList(pNode1);
    236 }
    237  
    238 // 输入的两个链表有一个空链表
    239 void Test5()
    240 {
    241     ListNode* pNode1 = CreateListNode(1);
    242     ListNode* pNode2 = CreateListNode(2);
    243     ListNode* pNode3 = CreateListNode(3);
    244     ListNode* pNode4 = CreateListNode(4);
    245     ListNode* pNode5 = CreateListNode(5);
    246  
    247     ConnectListNodes(pNode1, pNode2);
    248     ConnectListNodes(pNode2, pNode3);
    249     ConnectListNodes(pNode3, pNode4);
    250     ConnectListNodes(pNode4, pNode5);
    251  
    252     Test("Test5", NULL, pNode1, NULL);
    253  
    254     DestroyList(pNode1);
    255 }
    256  
    257 // 输入的两个链表都是空链表
    258 void Test6()
    259 {
    260     Test("Test6", NULL, NULL, NULL);
    261 }
    262  
    263  
    264 int main()
    265 {
    266     Test1();
    267     Test2();
    268     Test3();
    269     Test4();
    270     Test5();
    271     Test6();
    272     system("pause");
    273     return 0;
    274 }
    View Code

    参考资料

    https://blog.csdn.net/lingfeng2019/article/details/80778598

    https://blog.csdn.net/yanxiaolx/article/category/6250534(完整代码)

  • 相关阅读:
    利用世界杯,读懂 Python 装饰器
    利用python开发app实战
    Python协程(真才实学,想学的进来)
    Python 中的 10 个常见安全漏洞,以及如何避免(上)
    Python学到什么程度才可以去找工作?掌握这4点足够了!
    Hadoop Yarn调度器的选择和使用
    CSS 预处理器 Stylus分享
    我想写小说了怎么回事...
    新随笔-- from笔试
    我是不是有点胖了
  • 原文地址:https://www.cnblogs.com/wxwhnu/p/11421277.html
Copyright © 2011-2022 走看看