關於環的問題,
介紹幾個個經典的題目:
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...