日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

程序员面试题精选100题(35)-两链表的第一个公共结点[数据结构]

發(fā)布時間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序员面试题精选100题(35)-两链表的第一个公共结点[数据结构] 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目:兩個單向鏈表,找出它們的第一個公共結(jié)點。

鏈表的結(jié)點定義為:

struct?ListNode

{

??????int?????????m_nKey;

??????ListNode*???m_pNext;

};

分析:這是一道微軟的面試題。微軟非常喜歡與鏈表相關(guān)的題目,因此在微軟的面試題中,鏈表出現(xiàn)的概率相當高。

如果兩個單向鏈表有公共的結(jié)點,也就是說兩個鏈表從某一結(jié)點開始,它們的m_pNext都指向同一個結(jié)點。但由于是單向鏈表的結(jié)點,每個結(jié)點只有一個m_pNext,因此從第一個公共結(jié)點開始,之后它們所有結(jié)點都是重合的,不可能再出現(xiàn)分叉。所以,兩個有公共結(jié)點而部分重合的鏈表,拓撲形狀看起來像一個Y,而不可能像X

看到這個題目,第一反應(yīng)就是蠻力法:在第一鏈表上順序遍歷每個結(jié)點。每遍歷一個結(jié)點的時候,在第二個鏈表上順序遍歷每個結(jié)點。如果此時兩個鏈表上的結(jié)點是一樣的,說明此時兩個鏈表重合,于是找到了它們的公共結(jié)點。如果第一個鏈表的長度為m,第二個鏈表的長度為n,顯然,該方法的時間復雜度為O(mn)

接下來我們試著去尋找一個線性時間復雜度的算法。我們先把問題簡化:如何判斷兩個單向鏈表有沒有公共結(jié)點?前面已經(jīng)提到,如果兩個鏈表有一個公共結(jié)點,那么該公共結(jié)點之后的所有結(jié)點都是重合的。那么,它們的最后一個結(jié)點必然是重合的。因此,我們判斷兩個鏈表是不是有重合的部分,只要分別遍歷兩個鏈表到最后一個結(jié)點。如果兩個尾結(jié)點是一樣的,說明它們用重合;否則兩個鏈表沒有公共的結(jié)點。

在上面的思路中,順序遍歷兩個鏈表到尾結(jié)點的時候,我們不能保證在兩個鏈表上同時到達尾結(jié)點。這是因為兩個鏈表不一定長度一樣。但如果假設(shè)一個鏈表比另一個長l個結(jié)點,我們先在長的鏈表上遍歷l個結(jié)點,之后再同步遍歷,這個時候我們就能保證同時到達最后一個結(jié)點了。由于兩個鏈表從第一個公共結(jié)點考試到鏈表的尾結(jié)點,這一部分是重合的。因此,它們肯定也是同時到達第一公共結(jié)點的。于是在遍歷中,第一個相同的結(jié)點就是第一個公共的結(jié)點。

在這個思路中,我們先要分別遍歷兩個鏈表得到它們的長度,并求出兩個長度之差。在長的鏈表上先遍歷若干次之后,再同步遍歷兩個鏈表,知道找到相同的結(jié)點,或者一直到鏈表結(jié)束。此時,如果第一個鏈表的長度為m,第二個鏈表的長度為n,該方法的時間復雜度為O(m+n)

基于這個思路,我們不難寫出如下的代碼:

/// // Find the first common node in the list with head pHead1 and // the list with head pHead2 // Input: pHead1 - the head of the first list // pHead2 - the head of the second list // Return: the first common node in two list. If there is no common // nodes, return NULL /// ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {// Get the length of two listsunsigned int nLength1 = ListLength(pHead1);unsigned int nLength2 = ListLength(pHead2);int nLengthDif = nLength1 - nLength2;// Get the longer listListNode *pListHeadLong = pHead1;ListNode *pListHeadShort = pHead2;if(nLength2 > nLength1){pListHeadLong = pHead2;pListHeadShort = pHead1;nLengthDif = nLength2 - nLength1;}// Move on the longer listfor(int i = 0; i < nLengthDif; ++ i)pListHeadLong = pListHeadLong->m_pNext;// Move on both listswhile((pListHeadLong != NULL) &&(pListHeadShort != NULL) &&(pListHeadLong != pListHeadShort)){pListHeadLong = pListHeadLong->m_pNext;pListHeadShort = pListHeadShort->m_pNext;}// Get the first common node in two listsListNode *pFisrtCommonNode = NULL;if(pListHeadLong == pListHeadShort)pFisrtCommonNode = pListHeadLong;return pFisrtCommonNode; }/// // Get the length of list with head pHead // Input: pHead - the head of list // Return: the length of list /// unsigned int ListLength(ListNode* pHead) {unsigned int nLength = 0;ListNode* pNode = pHead;while(pNode != NULL){++ nLength;pNode = pNode->m_pNext;}return nLength; }

本文已經(jīng)收錄到《劍指Offer——名企面試官精講典型編程題》一書中,有改動,書中的分析講解更加詳細。歡迎關(guān)注。

博主何海濤對本博客文章享有版權(quán)。網(wǎng)絡(luò)轉(zhuǎn)載請注明出處http://zhedahht.blog.163.com/。整理出版物請和作者聯(lián)系。

總結(jié)

以上是生活随笔為你收集整理的程序员面试题精选100题(35)-两链表的第一个公共结点[数据结构]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。