今天看了
july的一篇經典文章《程式設計師程式設計藝術:第九章、閒話鍊錶追趕問題》,因為現在一直複習資料結構有關鍊錶的演算法,順便總結下,學習下july大牛的判斷鍊錶是否相交。出處:。
題目:給出兩個單向鍊錶的頭指標,判斷是否相交。
下面是july文章上面的解法:
分析:這是來自程式設計之美上的微軟亞院的一道面試題目。請跟著我的思路步步深入(部分文字引自程式設計之美):
直接迴圈判斷第乙個鍊錶的每個節點是否在第二個鍊錶中。但,這種方法的時間複雜度為o(length(h1) * length(h2))。顯然,我們得找到一種更為有效的方法,至少不能是o(n^2)的複雜度。
針對第乙個鍊錶直接構造hash表,然後查詢hash表,判斷第二個鍊錶的每個結點是否在hash表出現,如果所有的第二個鍊錶的結點都能在hash表中找到,即說明第二個鍊錶與第乙個鍊錶有相同的結點。時間複雜度為為線性:o(length(h1) + length(h2)),同時為了儲存第乙個鍊錶的所有節點,空間複雜度為o(length(h1))。是否還有更好的方法呢,既能夠以線性時間複雜度解決問題,又能減少儲存空間?
進一步考慮「如果兩個沒有環的鍊錶相交於某一節點,那麼在這個節點之後的所有節點都是兩個鍊錶共有的」這個特點,我們可以知道,如果它們相交,則最後乙個節點一定是共有的。而我們很容易能得到鍊錶的最後乙個節點,所以這成了我們簡化解法的乙個主要突破口。那麼,我們只要判斷倆個鍊錶的尾指標是否相等。相等,則鍊錶相交;否則,鍊錶不相交。
所以,先遍歷第乙個鍊錶,記住最後乙個節點。然後遍歷第二個鍊錶,到最後乙個節點時和第乙個鍊錶的最後乙個節點做比較,如果相同,則相交,否則,不相交。這樣我們就得到了乙個時間複雜度,它為o((length(h1) + length(h2)),而且只用了乙個額外的指標來儲存最後乙個節點。這個方法時間複雜度為線性o(n),空間複雜度為o(1),顯然比解法三更勝一籌。
上面的問題都是針對鍊錶無環的,那麼如果現在,鍊錶是有環的呢?還能找到最後乙個結點進行判斷麼?上面的方法還同樣有效麼?顯然,這個問題的本質已經轉化為判斷鍊錶是否有環。那麼,如何來判斷鍊錶是否有環呢?
總結:
所以,事實上,這個判斷兩個鍊錶是否相交的問題就轉化成了:
1.先判斷帶不帶環
2.如果都不帶環,就判斷尾節點是否相等
3.如果都帶環,判斷一煉表上倆指標相遇的那個節點,在不在另一條鍊錶上。
如果在,則相交,如果不在,則不相交。
下面先給出是否有環的演算法,就使用前面我的文章中的方法,但是題目的需要,增加了儲存了尾節點。
演算法和july的方法是一樣的,但是實現的方式有點不同而已。
//判斷鍊錶是否有環
bool isloop(node *head, node **firstloop, node **lastnode)
dowhile(second && second->next && first != second);
if(first == second)
else
return
false;
接下來是判斷是否相交的演算法,和july的**是一樣的,只是自己寫了一遍。學習了.....
//判斷兩鍊錶是否相交
//1.如果都不帶環,就判斷尾節點是否相等
//2.如果都帶環,判斷一煉表上倆指標相遇的那個節點,在不在另一條鍊錶上。
bool iscross(node *head1, node *head2)
bool isloop1 = isloop(head1, &firstloop1, &lastnode1);
bool isloop2 = isloop(head2, &firstloop2, &lastnode2);
if(!isloop1 && !isloop2) //兩個都無環
else
if(isloop1 != isloop2) //乙個有環,另乙個無環
else
//兩個都有環,判斷環裡的節點是否能到達另乙個鍊錶環裡的節點
} return
false;
}
學習到了新東西,感謝july的經典文章。。
鏈表面試題 判斷鍊錶是否相交(c語言)
一 問題描述 判斷兩個鍊錶是否相交,若相交返回交點,否則返回空。這裡假設鍊錶不帶環 由上圖我們可以得出鍊錶相交的兩個結論 1.兩鍊錶相交,第乙個相同的結點為鍊錶的交點 2.兩鍊錶相交,從交點向後的所有結點都相同 合二為一 二 解決思路 方法一 直觀法 思路 依次判斷第乙個鍊錶中的每個結點是否在第二個...
鏈表面試題 判斷兩個鍊錶是否相交
判斷兩個鍊錶是否相交,若相交,求交點。假設鍊錶不帶環 判斷兩個鍊錶是否相交,若相交,求交點。假設鍊錶可能帶環 採用對齊的思想。計算兩個鍊錶的長度 l1 l2,分別用兩個指標 p1 p2 指向兩個鍊錶的頭,然後將較長鍊錶的 p1 假設為 p1 向後移動l2 l1個節點,然後再同時向後移動p1 p2,直...
面試題 判斷兩個鍊錶是否相交(可能帶環)
判斷兩個鍊錶是否相交 可能帶環 這個問題我們可以根據是否帶環來分三種情況,情況一 兩個鍊錶都不帶環 情況二 其中有乙個鍊錶帶環 情況三 兩個鍊錶都帶環。下面我用一張來進行更詳細的分類,之後寫 也是按照這種劃分思想。bool isloop node phead 判斷乙個鍊錶是否帶環 if fast n...