檢查鍊錶是否有環,帶數學推導

2021-06-28 03:11:09 字數 1417 閱讀 7079

部落格已經搬家!請前往 閱讀本文。

給定下列列表(4指回2),若有快慢兩個指標,慢指標每次前進一步,快指標每次前進兩步,求兩指標何處相遇?

1-2-3-4

|___|

解:

設兩指標前進n次。n必定大於等於1。

in[1]:=

reduce[mod[n – 1, 3] == mod[2n – 1, 3], n, integers]

out[1]:=c1

∈z∧n

=3c1

然後尋找滿足上述條件(out[1])的最小的n。

in[2]:=

findminimum[, c]

out[2]:=}

所以n=3,即slow、fast兩指標在4處相遇。

一般化:給定乙個單鏈表,前面非迴圈部分有a個節點(長度為a),後面迴圈部分有l個節點(長度為l)。求快慢兩指標走多少次後相遇?

同理,設前進n次後相遇。(n>a)

快指標的位置=慢指標的位置??

∴(2n

?a)%

l=(n

?a)%

l2n?

a≡n?

a(modl)n

≡0(modl)

n=kl

(k?0

)公式1

公式2

公式1是同餘表示式,讀作2n-a和n-a在模l下同餘,

≡ 不是全等的意思,mod不是5 mod 3=2的意思。公式2應用同餘的性質,等號右邊移到左邊抵消掉。(注意到

(modl)

前的空格沒有?mod l表示對前面等號的左邊和右邊同時取餘數)

所以n是l的倍數。n不一定等於l,因為n必須大於a,而a與l的關係未知。因為n

≠l,所以2n

?n=k

l≠l 。這裡就證明了bluefeather說的「fastval – slowval equals the size of the loop」[1]是錯誤的。

能否求出l的具體值呢?答案是可以的。根據gocalf[2],兩指標相遇後,快指標暫停慢指標繼續走,兩指標第二次相遇時,慢指標走的次數就是環長。

給定任意帶環鍊錶,快慢指標相遇時走的次數為該帶環鍊錶的環長。

已知環長後,可以求非迴圈部分的長度a。

獲取甲乙兩個慢指標,甲先走l次,然後甲乙一起走。因為甲乙步長相同,他們之間始終保持l的差距。當乙第一次進入迴圈節時,由於甲乙差距為l,l為迴圈節長度,所以甲跟乙相遇。這時乙所走的步數就是a。 1.

↑bluefeather. share my o(n) complexity and constant space code. keep the original list. any comments. . 2014-12-12 [2015-01-08].2.↑

gocalf. 檢測單向鍊錶是否存在環. . 2011-10-14 [2015-01-08].

檢查單鍊錶中是否有環

用兩個指標,從頭節點開始遍歷,乙個指標a每次走1步,乙個指標b每次都2步。如果有環,兩個指標相遇前 b位於a後一位時,那麼a,b指標下次相遇。b位於a後兩位時,那麼a,b指標下下次即將相遇。建立鍊錶 public static node createlist int max return first...

js實現鍊錶翻轉以及檢查是否有環

input a b c d output d c b a 鍊錶翻轉 const reverselist function head return prev let a let b let c let d a.next b,b.next c c.next d reverselist a input a...

檢查鍊錶是否為回文

請編寫乙個函式,檢查鍊錶是否為回文。給定乙個鍊錶listnode phead,請返回乙個bool,代表鍊錶是否為回文。演算法實現如下 public class listnode class result public class palindrome result result ispalindro...