判斷倆個鍊錶是否相交

2021-06-19 22:00:21 字數 2108 閱讀 1110

《程式設計之美》上的一道微軟亞院題,判斷兩個兩個鍊錶是否相交,難度係數低。

描述如下:

給出倆個單向鍊錶的頭指標,比如h1,h2,判斷這倆個鍊錶是否相交。 

為了簡化問題,我們假設倆個鍊錶均不帶環。 

問題擴充套件: 

1.如果鍊錶可能有環列? 

2.如果需要求出倆個鍊錶相交的第乙個節點列? 

邏輯分析:

1、先考慮不帶環的鍊錶,最直觀的方法就是,遍歷h2鍊錶的每乙個元素,是否在h1中出現,最壞時間複雜度o(length(h1)*length(h2))。顯然,o(n^2)的複雜度,太差了。

2、借助空間,構造乙個雜湊表,將h1存入雜湊表,然後針對h2逐個查詢,是否在雜湊表中存在,借助雜湊表空間複雜度o(length(h1)),實現了o(length(h1)+length(h2))的時間複雜度。此時已為線性o(n)。

3、上面的兩種想法,通俗來講,都是所謂的「無腦思路」,即不通過數學或者邏輯上的分析,而採取的暴力或者偽暴力方法解決。實際上,通過簡單的分析,我們知道,兩個無環鏈表,如果有交集,那麼交集之後的點必然是重合的。換個角度,如果兩個無環鏈表相交,那麼最後乙個節點一定是公有的,而我們很容易能得到鍊錶的最後乙個節點,這成了我們簡化解法的乙個主要突破口。那麼,我們只要判斷倆個鍊錶的尾指標是否相等。相等,則鍊錶相交;否則,鍊錶不相交。

所以,先遍歷第乙個鍊錶,記住最後乙個節點。然後遍歷第二個鍊錶,到最後乙個節點時和第乙個鍊錶的最後乙個節點做比較,如果相同,則相交,否則,不相交。這樣我們就得到了乙個時間複雜度,它為o((length(h1) + length(h2)),而且只用了乙個額外的指標來儲存最後乙個節點。這個方法時間複雜度為線性o(n),空間複雜度為o(1),顯然比雜湊表儲存法更勝一籌。

上述的第三種思路,已經揭開了問題的本質,那麼現在擴充套件一下,如果鍊錶有環,怎麼辦?

4、鍊錶有環,乍一看,問題的複雜度要高得多,而我們原本的問題,就變成了這樣的形式:

1)首先判斷鍊錶是否有環,如果無,那麼比較h1和h2的尾結點是否重合,如果是,則相交,否則不相交。

2)如果鍊錶有環,那麼我們需要找出某種方法,來判斷。

**並茂的分析後,你會發現,有環其實也很簡單,只不過,我們定位的不再是尾結點,而是「尾結點」,也就是鍊錶成環的第乙個結點,如果這個結點公有,那麼鍊錶相交,反過來說更容易理解,如果這個結點不是公有的,那麼兩個鍊錶就是平行關係。(仔細想想為什麼?)

5、現在,我們將面臨著乙個問題,如何判斷鍊錶有環?其實很簡單,追及問題,弄兩個指標,第乙個每一次走一步,第二個每一次走兩步,若干次迴圈後,如果有環,那麼兩個指標必然相遇。(什麼,你問我沒環,沒環的話p2就提前領便當了,null了,還while個毛線。。。得出結論偷著樂吧。)

補充說明:如果乙個有環,乙個沒環,怎麼辦,好吧,我又在秀下限了,有點智商的看到這裡,都會表示絕對不會相交,沒錯,就是這麼一目了然。

//玉涵updated 2013.12.25。  

struct node  

;  //1.先判斷帶不帶環  

//判斷是否有環,返回bool,如果有環,返回環裡的節點  

//思路:用兩個指標,乙個指標步長為1,乙個指標步長為2,判斷鍊錶是否有環  

bool iscircle(node 

* head, node 

*& circlenode, node 

*& lastnode)     

if(fast 

== slow 

&& fast 

&& slow)     

else  

return 

false;  

}  //判斷帶環不帶環時鍊錶是否相交  

//2.如果都不帶環,就判斷尾節點是否相等  

//3.如果都帶環,判斷一煉表上倆指標相遇的那個節點,在不在另一條鍊錶上。  

bool detect(node 

* head1, node 

* head2)     

//兩個都有環,判斷環裡的節點是否能到達另乙個鍊錶環裡的節點  

else     

return 

false;  

}  return 

false;  

}  

另外,鍊錶追及問題,july在程式設計師程式設計藝術系列的第九篇做了全面講解,傳送門:

判斷倆鍊錶是否相交

給出倆個單向鍊錶的頭指標,比如h1,h2,判斷這倆個鍊錶是否相交。為了簡化問題,我們假設倆個鍊錶均不帶環。問題擴充套件 1.如果鍊錶可能有環列?2.如果需要求出倆個鍊錶相交的第乙個節點列?建立hash表 由於節點位址指標就是乙個整型,假設鍊錶都是在堆中動態建立的,可以使用堆的起始位址作為偏移量,以位...

判斷倆鍊錶是否相交

給出倆個單向鍊錶的頭指標,比如h1,h2,判斷這倆個鍊錶是否相交。為了簡化問題,我們假設倆個鍊錶均不帶環。問題擴充套件 1.如果鍊錶可能有環列?2.如果需要求出倆個鍊錶相交的第乙個節點列?建立hash表 由於節點位址指標就是乙個整型,假設鍊錶都是在堆中動態建立的,可以使用堆的起始位址作為偏移量,以位...

7 微軟亞院之程式設計判斷倆個鍊錶是否相交(鍊錶)

今天看了july的一篇經典文章 程式設計師程式設計藝術 第九章 閒話鍊錶追趕問題 因為現在一直複習資料結構有關鍊錶的演算法,順便總結下,學習下july大牛的判斷鍊錶是否相交。出處 題目 給出兩個單向鍊錶的頭指標,判斷是否相交。下面是july文章上面的解法 分析 這是來自程式設計之美上的微軟亞院的一道...