2 8 環路檢測

2021-10-03 14:30:06 字數 2595 閱讀 3062

template

<

typename t>

singlylinkednode

*findloopfirst

(singlylinkednode

* head)

// advance slow and fast pointers

s = s-

>

getnext()

; f = f-

>

getnext()

->

getnext()

;if(s == f)

}// reset slow pointer s to the head pointer

s = head;

// find the start point of linked list's loop

while

(true)}

return s;

}

這裡舉乙個例子對演算法加以說明,如圖1所示。演算法說明:設定兩個快慢指標fas

tfast

fast

和s lo

wslow

slow

,快指標每次移動兩個節點,慢指標slo

wslow

slow

每次移動乙個節點。如果鍊錶中有環,則當慢指標移動n=3

n=3n=

3步到鍊錶中的環的起始點(黑點)時,此時快指標和慢指標都進入到環中,由於單向鍊錶的原因,兩個指標將一直在環中無限迴圈執行。當慢指標移動n=3

n=3n=

3步到鍊錶中的環的起始點(黑點)時,快指標肯定位於環中的某個節點,此時可以認為快指標順時針滯後於慢指標。假設這裡滯後z

zz個節點(注意這裡是z

zz個節點不是快指標移動z

zz步,即此時從快指標指向的節點開始迭代取z

zz次nex

tnext

next

指標可以取到黑色節點的指標),由於快指標每次移動兩個節點,慢指標每次移動乙個節點,實際看來每次操作快指標可以追趕慢指標乙個節點。因此經過z

zz次操作後快指標和慢指標將指向同乙個節點。因此如果快慢指標發生碰撞,則說明鍊錶中存在環。

當慢指標移動n=3

n=3n=

3步到鍊錶中的環的起始點,黑點,時,快指標移動了6=2

∗n6=2*n

6=2∗

n步到達紅色節點,也即從鍊錶中的環的起始點,黑點,開始移動算起的第n=3

n=3n=

3個節點(此節點也可以說是從鍊錶中的環的起始點,黑點,開始移動算起的第n=11

n=11

n=11

或第n =19

n=19

n=19

個節點,這是因為環的原因,當n

nn超過loo

psiz

eloopsize

loopsi

ze時就會出現這種情況。因此這裡我們用n=n

%loo

psiz

e=3n=n \% loopsize=3

n=n%lo

opsi

ze=3

來代替此時快指標相對於環的起點移動的節點數。這裡loo

psiz

e=8loopsize =8

loopsi

ze=8

為鍊錶中環的節點個數)這時快指標順時針滯後於慢指標loo

psiz

e−n=

5loopsize-n=5

loopsi

ze−n

=5個節點。上面提到過經過loo

psiz

e−n=

5loopsize-n=5

loopsi

ze−n

=5次操作後快指標和慢指標將指向同乙個節點,綠點,這時綠點距離環的起點,黑點,loo

psiz

e−(l

oops

ize−

n)=n

=3loopsize-(loopsize-n)=n=3

loopsi

ze−(

loop

size

−n)=

n=3個節點,現在煉表頭節點距離環的起點,黑點,也是n=n

%loo

psiz

e=3n=n \% loopsize=3

n=n%lo

opsi

ze=3

個節點。此時將slow指標賦值為頭節點的指標,fas

tfast

fast

指標還是指向綠點,同時fas

tfast

fast

指標和slo

wslow

slow

指標同時向下乙個節點移動,每次移動乙個節點,當兩個指標指向的節點相同時,該節點即為環路的起始處。

該演算法的空間複雜度為o(1)。該演算法的時間複雜度為o(n),n為鍊錶中節點的個數。

圖1.

面試題 02 08 環路檢測

面試題 02.08.環路檢測 給定乙個鍊錶,如果它是有環鏈表,實現乙個演算法返回環路的開頭節點。有環鏈表的定義 在鍊錶中某個節點的next元素指向在它前面出現過的節點,則表明該鍊錶存在環路。示例1 輸入 head 3,2,0,4 pos 1 輸出 tail connects to node inde...

面試題 02 08 環路檢測

給定乙個鍊錶,如果它是有環鏈表,實現乙個演算法返回環路的開頭節點。如果鍊錶中有某個節點,可以通過連續跟蹤 next 指標再次到達,則鍊錶中存在環。為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置 索引從 0 開始 如果 pos 是 1,則在該鍊錶中沒有環。注意 pos 不...

Map中環路檢測

map是一種鍵值對的集合,因為鍵值在使用時很有可能呼互換,比方說鍵k1對應的值時v1,然而v1又能作為鍵,而之前的k1將會作為k1對應的值,就產生了環路了,在很多情況下。產生環路可能會使程式無休止的執行下去造成嚴重後果,因此需要檢測環路產生,當新插入的鍵值對會使原先的map產生環路,就拒絕這次插入 ...