今天參看《程式設計之美》之判斷鍊錶相交部分,上來就想到了判斷最後結點是否相等的方案,亦是該問題的較優方案,遂看了下擴充套件問題。
1)若有環該咋辦?
2)如何求出第乙個相交結點?
有環的求解在之前複習鍊錶部分,已經溫習過了,在此一筆帶過,採用兩個指標,分別走1步和2步,若有環,定會相遇(想必相遇大家都會判斷)。
那麼問題二求解第乙個相交結點部分,在《程式設計之美》裡面提到了乙個方案二採用hash的方法,由於鍊錶結點的下乙個指標都是指向不同的位址,若相同了就是相交部分了。故可採用此方法,分別從兩個煉表頭開始遍歷並更新hash表,若無此位址則繼續遍歷,否則返回第乙個相同的位址即可,但此方案的弊端在於需要構建乙個max(len1, len2)長度的hash表來存放結點位址。 是否有更優的方案呢?
《程式設計之美》的該問題的解法三,將鍊錶2的尾部指向2的頭,形成乙個環,這樣如果鍊錶1和2相交,那麼我們採用判斷環的方法即可知道1和2是否相交了。
接下來我們如何找到環相交的第乙個結點呢?
1步指標和2步指標相遇的時候,1步指標應該還沒有走遍鍊錶,而2步指標已經在環內走了至少一遍了。
我們可以做如此假設,環的長度為r,1步指標行走了s步與2步指標相遇,那麼2s = s + nr (n為環的倍數,不一定是整數倍)
s = nr
我們設 第乙個相交結點距離頭是a, 第乙個相交結點和相遇點距離是x, 此有環鏈表的長度為l,那麼有
a + x = nr (頭到相交結點 + 相交結點到相遇結點 即相遇的時候走的長度)
a + x = (n - 1) r + r
a + x = (n - 1) r + l - a (l - a 即為環的長度)
a = (n - 1) r + l - x - a
轉n-1環內可省去計算,即 a = l - x - a
此等式意味著,從想遇到繼續走到第乙個相交焦點的距離等於從頭到第乙個焦點的距離, perfect!只要讓相遇後的指標繼續往後走,同時讓乙個新指標從頭開始走,必然會在到第乙個相交結點處相遇,此時該結點正是我們想要的結點。
typedef struct linknode linknode, *plinknode;
// whether has a ring in the list
bool ring(plinknode a)
if (i == j)
return true;
return false;
}
plinknode find_first_crossed_node(plinknode l1)
if (!h1 || !h2)
return null;
plinknode h11 = l1;
while (h11 && h1)
return h11;
}
判斷兩個鍊錶是否相交並找出第乙個相交節點
引言 鍊錶問題是資料結構中的常見問題,對於面試 筆試都有很大的作用,那麼如何判斷兩個鍊錶是否相交並找出第乙個相交節點?分析 找出兩個鍊錶的交點首先就是判斷鍊錶是否相交,那麼首先來看什麼是兩個鍊錶相交?一 什麼是鍊錶相交?資料結構的鍊錶定義中儲存了指向下乙個元素的指標,如果當兩個鍊錶有交點時,即兩個鍊...
判斷兩個帶環鍊錶是否相交,並求出第乙個相交點
如果兩個鍊錶無環,判斷相交的方法在網上很多,此處不做討論。這裡只考慮兩個鍊錶都帶環的情況,如何判斷其是否相交。另外還有一種情況,就是乙個鍊錶不帶環,另乙個帶環。在這種情況,兩個鍊錶必然不想交,如果相交,則兩個鍊錶必然都帶環。ok,現在開始討論兩個帶環鍊錶相交的問題。1.既然帶環,先分別求出進入環的第...
如何判斷兩個鍊錶相交及找到第乙個相交點
我們學乙個演算法,一定是為了用吧,所謂 學以致用 嗎?那麼判斷兩個鍊錶是否相交有什麼用呢?這是因為一旦兩個鍊錶出現相交的情況,就可能發生這樣的情況,程式釋放了鍊錶la的所有節點,這樣就導致了另外乙個與之有相交節點的鍊錶lb中的節點也釋放了,而lb的使用者,可能並不知道事實的真相,這會帶來很大的麻煩。...