Skip to main content

Command Palette

Search for a command to run...

Algorithm 演算法 - 判圈系列 Floyd判圈算法(龜兔賽跑算法)

Floyd Cycle Detection Algorithm(Tortoise and Hare Algorithm)

Published

I am not a programmer just a leaner. Writing JavaScript, Python, and Go and doing something on Kubernetes.

簡介 Intro

該算法據高德納稱由美國科學家羅伯特·弗洛伊德發明,但這一算法並沒有出現在羅伯特·弗洛伊德公開發表的著作。一個可以在有限狀態機、迭代函數或者鍊表上判斷是否存在環,求出該環的起點與長度的算法。

演算法解釋

下圖是這整個演算法的邏輯思維流程圖

image.png

演算法可以算是一種 Two-Pointer 的解法,可以想像在操場上跑步,在一個環當中,一個跑比較慢一個跑比較快,快的一定會追上慢的,以這個概念來判斷是否存在迴圈。

範例會用以下的圖作參考

circularlinkedlist.png

烏龜是 t 每次走一步、兔子是 r 每次走兩步。

  1. tr 從 3 開始出發
  2. t 到 2、r 到 0
  3. t 到 0、r 到 2
  4. t 到 -4、r 到 -4 =>相遇了,所以判斷有迴圈存在

而如果不存在迴圈的話,r 會先走到結尾沒有下一個節點,所以當 r = null 的時候就知道迴圈不存在了。因為使用 Two-Pointer 的方式所以空間複雜度就只需要常數而已,而時間複雜度只有 O(n)n 是節點數

程式範例可以參考:LeetCode Solution, Easy, 141. Linked List Cycle

進階

進階的題目就像是 LeetCode Solution, Medium, 142. Linked List Cycle II 是要找出迴圈的連接點。

延續上面的範例,c 是迴圈的長度、l 是起點到迴圈連接點的長度、x 是連接點到第一次相遇點的長度。 從第一次相遇點的位置到連接點 f = c - x

r = l + x + n * c // c 會乘上 n 是因為在遇到 t 之前不確定已經先走了幾圈
t = l + x

l + x + n * c = 2 * (l + x)  // r 每次走兩步, t 只走一步,所以總長上 r 會走 t 的兩倍
l + x + n * c = 2 * l + 2 * x
n * c = l + x      // 簡化的結果,從起始點到相遇點是迴圈的倍數 

l + x = (n - 1) * c + c
l + x = (n - 1) * c + f + x
l = (n - 1) * c + f

最後的結果 l = (n - 1) * c + f 可以看到 lf 的長度就只差在迴圈長度的倍數,所以當今天常數 n = 1,就可以發現 l = f 了,因此當同時有兩個人分別從起點和相遇點開始走時,最後會在連接點相遇,由此找出連接點在哪。

Reference

More from this blog

如何開始入門軟體工程領域 - 名詞解釋(長期更新)

現在應該開始有很多人想要踏入軟體工程的領域,但在進入這個領域之前,覺得先了解一些名詞,可以在入門時更有方向也更知道要用什麼關鍵字去找尋有用的資訊。這篇文章就是想要幫助想要入門的人理解一些軟體工程裡的專有名詞。 作業系統 這一區塊主要解釋跟作業系統層面相關的名詞 英文中文解釋 Operation system 簡稱 OS | 作業系統 | 就是電腦的作業系統,是三大作業系統分別是:Linux、Windows、macOS | | Linux | | 自由和開放原始碼的 UNI...

May 10, 2023

我的 MacBook Pro (Apple Silicon) 設定

現在開始因為 ChatGPT 的出現,各種 AI 助手的功能都跑出來了。想想自己用了許久的環境設定也應該要來重新審視和建立新的開發環境了,僅此紀錄我個人的環境配置步驟和設定。 環境前置步驟 還原 MacBook Pro 至全新環境 macOS(全部資料刪除) 設定好初始設定後,登入 Apple ID 進入 App Store 確定 macOS 版本和預設 APP 都更新到最新 macOS 版本 到系統設定調整所有設定至個人習慣的設定 三指拖移 觸控板手勢開啟 防火牆開啟 輸入法設定...

Apr 25, 2023

ChatGPT 下的發展預想

從 ChatGPT 問世到現在,有許許多多的文章和討論出來。先從最早的 Google 要完蛋了,到後來的工作要被取代了,工程師失業了。 我就比較沒有想要馬上出來評論一下,我喜歡讓子彈飛一會兒。跟討論一下我自己比較在意的討論點。 Google 為什麼慢了? 結論:因為他需要更小心 很多人說 Google 怎麼被微軟搶先了一步。剛開始 Bing 說要加上 AI 的時候大家都在說 Google 怎麼慢了。我就馬上跑去看 OpenAI 的網站,靠北呀啊就 Azure 贊助的。那當然在正式上線 ChatG...

Mar 23, 2023

不工程的攻城獅

223 posts

I am not a programmer because I am not good at programming. But I do programming. Love to learn new things. An animal lover and a dancer. My oshi is 潤羽るしあ.