求單鏈表交點

2021-09-23 20:21:14 字數 2171 閱讀 9667

今天面試時,面試官問了這樣乙個問題:兩個單鏈表相交,怎麼求交點。所謂相交,就是兩個節點的next指標相同。

例如,對於上圖的兩個單鏈表,遍歷上面的單鏈表得到列表:a, b, c, d, e, f, g;遍歷下面的單鏈表得到列表:h, i, e, f, g。因為單鏈表相交之後就匯合了,匯合之後的節點就是一樣的,而匯合之前的節點不一樣,所以同步逆序遍歷這兩個列表:g-g, f-f, e-e, d-i……於是,e節點就是交點。

這種做法時間複雜度為\(o(n)\),但空間複雜度為\(o(n)\),有沒有空間複雜度更低的解法呢?

如果使用hashmap儲存,先遍歷上面的單鏈表,並把節點儲存到hashmap裡,然後遍歷下面的單鏈表,每次都看當前節點是否已經存在於hashmap中,如果存在,則該節點就是交點。採用這種做法,不必把兩個單鏈表都遍歷完,不過依然沒有降低空間複雜度。

另一種思路是暴力法,也就是遍歷這兩個鍊錶,判斷第乙個鍊錶的每個節點是否在第二個鍊錶中,這種做法的時間複雜度為\(o(n^2)\)。

這個問題比較麻煩的地方在於,這兩個單鏈表相交之前的部分的長度可能不一致。假如這兩個單鏈表長度一致,那麼指標p、q只要同步移動,然後首次相遇的地方就是交點了。

例如,對於圖中的兩個單鏈表,假如上面的單鏈表沒有a, b節點,指標p初始指向c節點,那麼,指標p、q只要同步移動兩次,就會在節點e相遇,e節點就是交點。那麼,我們要怎麼樣讓指標p指向c節點後,指標p、q才同步移動呢?

其實很簡單,先遍歷一下這兩個單鏈表,得到它們的長度,然後讓長的單鏈表的指標先走長度之差步,就可以了!對於圖中的兩個單鏈表,上面的單鏈表長度為7,下面的單鏈表長度為5,兩個單鏈表的長度之差為2,且上面的單鏈表更長,那麼就讓指標p先走2步(這樣就到了c節點),然後指標p、q同步移動即可。

這個問題比較簡單。顯然,如果兩個單鏈表相交,則必然是「y」形的,而不是「x」形的。只需要判斷兩個單鏈表中是否存在相同的元素即可。

如果這兩個單鏈表相交,則尾節點必然相同,因此,直接遍歷到尾節點,然後判斷尾節點是否相同即可。還可以把節點存到雜湊表,在遍歷第二個單鏈表時,判斷節點是否在雜湊表中已存在,若已存在則相交。

這個可以採用快慢指標的技巧。初始時,指標p、q都位於初始節點,然後每次指標p移動乙個節點,指標q移動兩個節點,則指標p、q必然在環內相遇。

為什麼指標p、q必然在環內相遇呢?這是因為在環內,可以看成是指標q「追趕」指標p,每次「追趕」1乙個節點(也就是相對距離-1),所以必然能相遇。而且,指標p、q相遇時,指標p在環內走過的距離不會超過環的長度。

假設單鏈表起點到第乙個在環裡的節點的距離為\(n\),快慢指標p、q在環內相遇,第乙個在環裡的節點到相遇點的距離為\(f\),環的長度為\(l\)。

那麼,顯然,指標p、q相遇時,指標p走過的距離為\(n+f\),指標q走過的距離為\(n+f+xl\)(之所以是\(xl\)是因為,假如\(n\)較大而\(l\)較小,那麼指標q可能在環內轉了好幾圈才和指標p相遇)。顯然有:

\[ 2(n+f) = n+f+xl \]

故 \(n = xl-f, x>0\),或者寫為:

\[n = l - f + xl \quad x\geq0\]

而指標p、q的相遇點到第乙個在環裡的節點的距離為\(l-f\)。指標p從單鏈表的起點開始移動,每次移動1個節點,指標q從相遇點開始移動,每次也移動1個節點,那麼,指標p、q就會在第乙個在環裡的節點處相遇。

對於本文最開始的問題,還有一種比較特殊的解法。先遍歷其中乙個鍊錶,遍歷到尾節點時,將尾節點的next指標指向另乙個鍊錶的起點,然後,問題就轉化為求單鏈表中第乙個在環裡的節點了。

後記:在leetcode上刷到了原題:160. intersection of two linked lists,還是要多刷題啊!

求兩單鏈表交點

題目 已知兩單鏈表有交點,給出兩單鏈表的頭指標,求交點位置。思路 自交點至公共尾部的結點都是相同的,則分別遍歷兩個鍊錶,並將每個結點的指標分別儲存在兩個陣列中,然後從兩陣列尾部開始比較,到兩指標值開始不同時,前一位置即使指向交點的指標。思路 分別遍歷兩鍊錶,得到各自的長度l1 l2,然後長的減短的得...

求兩個單鏈表的交點(可能帶環)

先簡單分析 兩個單鏈表相交分如圖幾種情況 實現如下 判斷鍊錶是否帶環,若帶環求入口點 pnode iscirclelist pnode phead pnode pfast phead next next pnode pslow phead next while pfast pslow null pf...

求單鏈表長度

include include typedef struct linknode node,linklist linklist表示結構體指標 linklist createlist end int n 尾插法建立鍊錶 void showlist linklist l 輸出鍊錶內容 int linkle...