兩鍊錶相交問題

2021-08-18 13:52:33 字數 2224 閱讀 5123

(1)兩個鍊錶相交,那麼兩個鍊錶中的節點一定有相同位址。

(2)兩個鍊錶相交,那麼兩個鍊錶從相交節點開始到尾節點一定都是相同的節點。

(問:為什麼? 答:因為每乙個節點最多只能有乙個下一節點,因此在相交節點之後,鍊錶不可能再分為兩個鍊錶)

根據兩個鍊錶是否存在環來分類討論

無環的情況有兩種比較快速的解決方式,這兩種方式本質上都是基於一、問題分析中的第二要素

① 製造環法

如果兩鍊錶相交,只會有上面這種情況(兩鍊錶合為乙個鍊錶),如果還有其他的情況,請拍磚

那麼何為製造環法呢,依然看圖

首先遍歷鍊錶a,遍歷到a的尾節點時,將a的尾節點的下一節點設定為鍊錶b的頭結點。這樣就會出現兩種情況:

無環:(分析)因為兩鍊錶不存在交點,將a的尾節點的下一節點設定為鍊錶b的頭結點後,這兩個鍊錶就成為了乙個無環鏈表

有環:(分析)因為兩鍊錶存在交點,因此在將a的尾節點的下一節點設定為鍊錶b的頭結點後,從相交點開始,原來的鍊錶b就構成了乙個環(本質:如果兩鍊錶存在交點,則尾結點一定相同。因此鍊錶a的尾結點也就是鍊錶b的尾結點,將鍊錶a尾結點的下一節點設定為鍊錶b的頭結點就等價於將鍊錶b的尾結點的下一節點設定為鍊錶b的頭結點,故一定會構成環)

因此我們可以先將鍊錶a的尾節點的下一節點設定為鍊錶b的頭節點。如果存在環,則ab鍊錶存在交點;否則就是兩條互不相干的鍊錶(如何判斷鍊錶是否存在環,請參考我另外一篇部落格。這篇只分析鍊錶相交問題)

那麼問題來了,如何尋找相交點?其實很簡單,仔細看看上圖就很容易發現,這個環的入口結點就是兩鍊錶的相交點

② 比較尾節點法

相比上種方法,這種方法簡直就是一點就通(之所以沒放在第乙個來講是擔心你們看了後就不認真看第二個,別打我~)

還是這張圖,還是基於一、問題分析中的第二要素。

聰明的人肯定已經知道我接下來要說什麼了,那麼帥氣的人就仔細聽好

直接比較ab鍊錶的尾結點是否相等即可

直接比較ab鍊錶的尾結點是否相等即可

直接比較ab鍊錶的尾結點是否相等即可

相等則表示有交點,不相等則表示沒有交點。

那麼問題又來了,這種方式又應該怎麼尋找相交節點呢?

先遍歷鍊錶a得出鍊錶a的長度s1

在遍歷鍊錶b得出鍊錶b的長度s2

比較,選擇長的那個鍊錶(這裡假設是鍊錶a長)

先讓鍊錶a走s1-s2個節點(每次走乙個節點,在鍊錶b開始走之後也接著走);然後鍊錶b也開始走,鍊錶b每遍歷乙個節點都和鍊錶a當前的結點比較。第乙個相等的節點就是交點

有環的話一般是兩個鍊錶都存在環

因為如果乙個鍊錶存在環而另外乙個鍊錶不存在環那麼這兩個鍊錶肯定不存在交點(問:為什麼?答:自己畫圖感受一下就會意識到這個問題有多麼的愚蠢,當然如果你真的證明了存在這種情況。那麼恭喜你肯定會在學術界引起轟動 )

而且如果兩個鍊錶都有環,如果它們有交點的話。那麼它們一定共用乙個環。如圖下

兩個鍊錶一定是在環的某個地方進入這個環,如果還有其他情況,歡迎拍磚(博主頭鐵2333)

現在,我們可以採用快慢指標來判斷兩個有環的鍊錶是否存在交點。因為這個環是兩個鍊錶共用的,所以只要兩個鍊錶使用快慢指標,就一定會發生指標碰撞。

何為快慢指標,這裡簡單的提及一下。就是放兩個指標,乙個指標一次走兩個節點(也可以走3、4甚至n個),乙個節點一次走乙個節點。這樣只要存在環,那麼兩個節點就一定會相遇(其實一開始我也懷疑會不會走得快的那個節點會不好剛好跳過走得慢的那個節點,不過仔細畫畫圖即可知道,一定會相遇。就像博爾特和宋小寶在乙個環裡面跑步,他們一定就相遇多次;反之,如果不存在環,則他們永遠也不會相遇)

在鍊錶a中放快指標,在鍊錶b中放慢指標(反之也可以),然後每次遍歷都判斷兩節點是否相等,只要相等就一定存在交點

那麼問題又來了?如何尋找相交點?

這個問題博主還在思考,如果入口點不同的話,那應該是不存在交點吧….

歡迎拍磚和參與討論~

鍊錶相交問題

1 判斷兩個鍊錶是否相交 假設兩個鍊錶均不帶環 有四種方法 解法1 直觀的想法 判斷第乙個鍊錶的每個節點是否在第二個鍊錶中,這種方法的時間複雜度為o length h1 length h2 解法2 利用計數的方法 對第乙個鍊錶的節點位址進行hash排序,建立hash表,然後針對第二個鍊錶的每個節點的...

鍊錶相交問題

問題描述 給定兩鍊錶的頭結點,判斷兩鍊錶是否存在公共部分 相交 若相交返回相交的第乙個節點。經分析發現該問題可以分成如下兩個子問題進行解決。子問題一 兩無環鏈表是否相交 演算法一 假設list1長度為l1,list2長度為l2,假設公共部分長為m,由l1 l2 m l2 l1 m可知第一路先遍歷li...

求鍊錶相交節點問題

給定兩個 單向 鍊錶,判定它們是否相交並返回交點。請注意相交的定義基於節點的引用,而不是基於節點的值。換句話說,如果乙個鍊錶的第k個節點與另乙個鍊錶的第j個節點是同一節點 引用完全相同 則這兩個鍊錶相交。輸入 intersectval 8,lista 4,1,8,4,5 listb 5,0,1,8,...