鍊錶中環問題詳解

2021-08-15 20:24:48 字數 1657 閱讀 6390

這個問題在面試中是老生常談的問題了,而且,解決這類問題的主要方法就是追擊法,因此,這篇部落格中只講解這種方法求解環的問題。

這裡給出三個鍊錶中環的問題:

這裡給出一副,所有的討論都在這上進行。

這個問題很好解決,設定兩個指標ptr_1, ptr_2在a處,讓ptr_1以1的速度往後走(即每次移動乙個位置),ptr_2以2的速度往後走,如果鍊錶中存在環,那麼ptr_1, ptr_2都會進入環中,ptr_2會以2的速度追擊ptr_1,而且ptr_2一定可以追上ptr_1(即ptr_2 == ptr_1);如果鍊錶中不存在環,那麼ptr_1ptr_2之中一定有乙個等於空指標。

bool judge_the_circle(listnode *phead)

return ptr_1 != nullptr && ptr_1 == ptr_2;

}

還是上面那幅,問題一中講到如果有環,ptr_1ptr_2一定會相遇,但是相遇在哪個地方呢?是不是沒有思考過這個問題,要想知道相遇在哪個地方,還要從這兩個指標的速度入手。

與上個問題一樣的做法,只不過這次我要分一下運動的階段了:

上面數學分析的既是演算法的原理,也是演算法的步驟,因此可以很清楚地寫出**。

listnode* entrynodeofloop(listnode* phead)

while (ptr_1

!= nullptr && ptr_2

!= nullptr &&

ptr_2

->

next

!= nullptr && ptr_1

!= ptr_2);

if (!(ptr_1

!= nullptr && ptr_2

!= nullptr && ptr_2

->

next

!= nullptr))

return

nullptr;

for (ptr_1 = phead; ptr_1

!= ptr_2; ptr_1 = ptr_1

->

next, ptr_2 = ptr_2

->

next) {}

return

ptr_1;

}

理解了問題二,這個問題就很簡單了,呼叫問題二的函式,求出環的入口,然後讓ptr_1走到環的入口,然後讓ptr_1再次走到環的入口,統計下路程,就是環長。

int lengthofloop(listnode* phead)

while ((ptr = ptr->next) != enternode);

return ret;

}

這類問題慢慢分析就好了,多畫圖。

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

關於環的問題,介紹幾個個經典的題目 1.求鍊錶倒數第k個結點 最經典,最常見的解法就是,設定兩個指標p1,p2,一開始分別指向頭結點,首先p2先移動k個節點,之後開始p1,p2每次移動1個節點,直到p2達到最後乙個節點位置,那麼p1指向的就是倒數第k個節點。不過這種解法主要是針對單鏈表,且鍊錶中不存...

鍊錶 尋找鍊錶中環的起點

給定乙個單鏈表,若該鍊錶有環,返回環的起點,若沒有,返回null 基本思路 每遇到乙個節點,計數器 當遇到訪問次數為2時,返回該節點,否則在迴圈結束前還沒有找到,則返回null class solution return null 高階思路 雙指標思路,證明 慢指標速度為v 那麼快指標速度為2v 第...

鍊錶 鍊錶中環的入口結點

給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。知識點回顧 快慢指標 思路 使用快慢指標 假設有p,q兩指標,p每步跨乙個結點,q每步跨兩個結點。那麼經過k步之後q比p多走過的結點數為k。如果鍊錶中沒有環,那麼q永遠在p的前面,兩指標不會相遇。如果鍊錶有環,且環中結點個數為...