1. 簡述
給出兩個鍊錶的頭指標,比如h1,h2,判斷這兩個鍊錶是否相交。這裡是為了簡化問題,我們假設兩個鍊錶不帶環。
擴充套件:如果鍊錶可能有環呢?
擴充套件:如何求出兩個相交鍊錶的相交的第乙個節點。
2. 分析
這道題,個人感覺理解的還是相對比較清楚完整。主要就是兩個問題,問題一,兩個鍊錶是否相交,問題二,兩個鍊錶如果相交,求得相交第乙個節點。
如果兩個鍊錶相交,那麼要麼兩個鍊錶都沒有環,要麼都有環。所以我們首先判斷h1和h2是否有環:三種情況:乙個有環乙個沒環(這種情況說明肯定不相交),兩個都有環(需要進一步判斷),兩個都沒有環(需要進一步判斷)。
乙個鍊錶是否有環的判斷方法很簡單,就是兩個指標,乙個一次走一步,另乙個一次走兩步,如果有環,那麼兩個指標早晚進入環,兩個指標的相對速度正好是1,因此距離會一點一點減少,直到兩個指標相遇,如果其中乙個指標變為空了,說明不存在環。
對於都沒有環的兩個鍊錶:如果相交比如是從尾部向頭部的若干個節點相交(至少1個),可以直接判斷兩個鍊錶的最後乙個節點位址是否相同。如果要尋找第乙個相交的節點,也很容易,計算兩個節點的長度差,假設為k,讓較長的鍊錶先走k步,然後,每走一步前先判斷節點位址是否相等即可。
對於都有環的兩個鍊錶:如果他們相交那麼兩個鍊錶的環的部分必然是重合的,因為乙個鍊錶如果有環必然是形如數字6的情況。注意這裡不能用兩個指標分別從兩個鍊錶走,因為,如果鍊錶相交,那麼一快一慢的指標會相交,但是如果鍊錶不相交,那麼兩個指標永遠都不會相交,而且都在各自的環中不停的走,這樣無法結束迴圈的。這裡需要轉換思路,首先求得鍊錶進入環的第乙個節點,因為這個節點也在環上,所以這個節點必然是相交的,只要判斷這個節點位址是否相同即可。對於相交的第乙個節點,其實如果找到兩個鍊錶進入環的第乙個節點了,那麼從頭節點到這個節點,就轉化為兩個單鏈表的形式了,進入環的第乙個節點相當於單鏈表的最後乙個節點。
關鍵在於尋找帶環鍊錶的進入環的那個節點。方法如下:兩個指標,乙個走一步,乙個走兩步,在環中相遇位置為x,然後從頭節點和x位置,分別一步一步的走,每次判斷是否相遇,相遇點就是所求節點。
證明如下:假設頭節點位置為a,第乙個節點為m,相遇節點為x,環長為len。
因為快節點每次比慢節點快一步,慢節點進入後快節點不用一圈就能趕上慢節點了。
慢節點走的路程 = am + mx
快節點走的路程 = am + mx + n * len
2*(am + mx ) = am + mx + n *len
am + mx = n*len
am = (n-1)*len + xm 就是這句話了,說明從a到m的距離與x到m的距離,同餘環長。因此分別從a和x走,必然相交於x節點。
3. 參考
程式設計之美,3.6節,程式設計判斷兩個鍊錶是否相交
程式設計之美 3 6 判斷兩個鍊錶是否相交
問題描述 給出兩個單向鍊錶的頭指標 h1,h2 判斷這兩個鍊錶是否相交。假設兩個鍊錶均不帶環。解法一 直觀的想法 判斷第乙個鍊錶胡每乙個節點是否在第二個鍊錶中。時間複雜度為o length h1 length h2 解法二 利用計數的方法 如果兩個鍊錶相交,就會有共同的節點。我們可以把第乙個鍊錶的節...
程式設計之美 判斷兩個鍊錶是否相交
首先,判斷乙個鍊錶是否有環?對於這個問題 可以用兩個指標,剛開始都指向頭節點,然後乙個指標每次向後移一步,另乙個指標每次向後移兩步,如果最後移兩步的指標為空時,說明無環,如果最後兩個指標相等,說明有環。如果把第一指標看成靜止,則相當於第二個每次走一步,所以在那個環上時,是一定能相遇的。如何找到這個鍊...
3 6 程式設計判斷兩個鍊錶是否相交
一 題目 輸入乙個單項鍊表,找出該鍊錶的倒數第k個節點。解法 設立兩個指標,先讓第乙個指標先往前走k步,然後第二個指標放到鍊錶開頭。然後兩個鍊錶一起往後走,當第乙個鍊錶到達鍊錶尾部的時候,後面那個鍊錶所在的位置就剛好是鍊錶的倒數第k個節點!struct node node funtion node ...