關於鍊錶追趕 鍊錶中環的問題

2021-09-01 03:48:24 字數 1427 閱讀 7625

關於環的問題,

介紹幾個個經典的題目:

1.求鍊錶倒數第k個結點

最經典,最常見的解法就是,設定兩個指標p1,p2,一開始分別指向頭結點,首先p2先移動k個節點,之後開始p1,p2每次移動1個節點,直到p2達到最後乙個節點位置,那麼p1指向的就是倒數第k個節點。

不過這種解法主要是針對單鏈表,且鍊錶中不存在環的,如果是雙向鍊錶,或者是存在環的鍊錶呢?

在判斷是否在最後乙個節點上就會出現問題了,ps.迴圈鍊錶中判斷最後乙個節點就需要檢視其pre指標指向的節點是否是剛才遍歷過的節點。對於存在環的節點判斷最後乙個節點就有點麻煩了:

判斷乙個鍊錶是否存在環

環的定義如上:

定義兩個指標,開始的時候分別指向head,之後p1每次移動乙個節點,p2每次移動兩個節點,如果p2遇到null 的時候,不存在換否在p1,p2肯定在環內相遇。當p1==p2的時候,退出,存在環

判斷兩個鍊錶是否相交

對於這個問題,這裡的相交不會存在「x」的相交,而是「y」形狀的相交。

解法一使用兩個for迴圈來同時遍歷兩個陣列,來發現首個相同的節點,不過時間複雜度會達到o(m*n)

解法二使用hash表儲存第乙個鍊錶的所有元素,通過遍歷第二個鍊錶,檢查是否相同的節點在hash表中,有的話則說明兩個鍊錶有相同的子串行,否則就沒有。時間複雜度為o(m+n),空間複雜度為o(m),不是很理想

解法三如果鍊錶相交則鍊錶的最後乙個節點一定是相同的,我們只需要判斷最後乙個節點是否相同即可。時間複雜度為o(m+n),空間複雜度減少到o(1)

當然上述幾種方法都是建立在無環鏈表的基礎之上的。

所以總結如下解決辦法:

1.先判斷帶不帶環

2.如果都不帶環,就判斷尾節點是否相等

3.如果都帶環,判斷第乙個鍊錶上是否存在環時---倆指標相遇(在環中相遇)的那個節點,在不在另一條鍊錶上。如果在,則相交,如果不在,則不相交。

判斷乙個存在環的鍊錶的環的第乙個節點

在網上看到乙個解決辦法,類似龜兔賽跑的原理,定義兩個指標p1,p2。p2一直向前走,p1,也是向前走,每走一步檢查下是否趕上p2,如果趕上了,就從頭再跑,此時p2向前走一步,如果沒趕上,則繼續往前走,此時p2停下等待,如此迴圈,直到,p1==p2->next,此時p2計時所求的點。

求兩個相交鍊錶的首個交點

解法1:

使用兩個for迴圈來同時遍歷兩個陣列,來發現首個相同的節點,不過時間複雜度會達到o(m*n)

解法2每個節點新增乙個vist訪問標誌位,來表示已經訪問過的節點。首先遍歷第乙個鍊錶,將訪問位置true,然後遍歷第二個鍊錶,當發現vist的位true時,則這個節點就是兩個鍊錶相交的首個交點。時間複雜度為o(m+n)

解法3:

首先求出兩個鍊錶的長度c,d;

求出f=abs(c-d);

較長的那個鍊錶首先遍歷f個長度,然後兩個鍊錶同時開始向下遍歷,並進行比較,第乙個相等的即為兩個鍊錶相交的首個交點。

鍊錶追趕問題

題目 輸入乙個單向鍊錶,輸出該鍊錶中倒數第k個結點,鍊錶的倒數第0個結點為鍊錶的尾指標 分析 首先這個鍊錶時單向鍊錶,並且我們也不知道鍊錶的長度,那麼僅僅憑藉乙個指標來找到倒數第k個節點,就需要知道鍊錶的長度,因此需要先遍歷整個鍊錶,得到鍊錶的長度過後,然後再從頭結點開始尋找,這種方法顯然很笨,那麼...

(9)鍊錶追趕

include using namespace std 認真分析具體情況,當把問題分析透了時,解決方案也就一目了然了 1.如果兩個都沒有環 看結尾節點是否相同 2.如果乙個有環,乙個沒有,則必定分離 3.如果兩個都有環 node1,node2 分別是入環節點 看是否能從node1遍歷到node2 如...

鍊錶中環問題詳解

這個問題在面試中是老生常談的問題了,而且,解決這類問題的主要方法就是追擊法,因此,這篇部落格中只講解這種方法求解環的問題。這裡給出三個鍊錶中環的問題 這裡給出一副,所有的討論都在這上進行。這個問題很好解決,設定兩個指標ptr 1,ptr 2在a處,讓ptr 1以1的速度往後走 即每次移動乙個位置 p...