天天看點

Floyd判圈算法 Floyd Cycle Detection Algorithm

2018-01-13 20:55:56

Floyd判圈算法(Floyd Cycle Detection Algorithm),又稱龜兔賽跑算法(Tortoise and Hare Algorithm),是一個可以在有限狀态機、疊代函數或者連結清單上判斷是否存在環,求出該環的起點與長度的算法。該算法據高德納稱由美國科學家羅伯特·弗洛伊德發明,但這一算法并沒有出現在羅伯特·弗洛伊德公開發表的著作中。

如果有限狀态機、疊代函數或者連結清單上存在環,那麼在某個環上以不同速度前進的2個指針必定會在某個時刻相遇。同時顯然地,如果從同一個起點(即使這個起點不在某個環上)同時開始以不同速度前進的2個指針最終相遇,那麼可以判定存在一個環,且可以求出2者相遇處所在的環的起點與長度。

一、算法描述

如果有限狀态機、疊代函數或者連結清單存在環,那麼一定存在一個起點可以到達某個環的某處(這個起點也可以在某個環上)。

初始狀态下,假設已知某個起點節點為節點S。現設兩個指針t和h,将它們均指向S。

接着,同時讓t和h往前推進,但是二者的速度不同:t每前進1步,h前進2步。隻要二者都可以前進而且沒有相遇,就如此保持二者的推進。

當h無法前進,即到達某個沒有後繼的節點時,就可以确定從S出發不會遇到環。

反之當t與h再次相遇時,就可以确定從S出發一定會進入某個環,設其為環C。

如果确定了存在某個環,就可以求此環的起點與長度。

環長度:上述算法剛判斷出存在環C時,顯然t和h位于同一節點,設其為節點M。顯然,僅需令h不動,而t不斷推進,最終又會傳回節點M,統計這一次t推進的步數,顯然這就是環C的長度。

環入口:為了求出環C的起點,隻要令h仍均位于節點M,而令t傳回起點節點S,此時h與t之間距為環C長度的整數倍。随後,同時讓t和h往前推進,且保持二者的速度相同:t每前進1步,h前進1步。持續該過程直至t與h再一次相遇,設此次相遇時位于同一節點P,則節點P即為從節點S出發所到達的環C的第一個節點,即環C的一個起點。

環入口算法的證明:

Floyd判圈算法 Floyd Cycle Detection Algorithm
假設慢指針到相遇點的距離為l,則快指針的路程為2l,環的長度為r。 l = x + y; 2l = l + nr; ==> nr = x + y ==> x = nr - y 那麼此時,将相遇點的慢指針調到起始點,快指針行進速度和慢指針保持一緻,那麼當慢指針走了x的路程時,快指針走了nr - y,正好兩者在環的入口處相遇。

二、僞代碼描述

三、算法複雜度

時間複雜度:注意到當指針t到達環C的一個起點節點P時(此時指針h顯然在環C上),之後指針t最多僅可能走1圈。若設節點S到P距離為m,環C的長度為n,則時間複雜度為O(m+n),是線性時間的算法。

空間複雜度:僅需要創立指針t、指針h,儲存環長n、環的一個起點P。空間複雜度為O(1),是常數空間的算法。

四、應用

對于有限狀态機與連結清單,可以判斷從某個起點開始是否會傳回到通路過運作過程中的某個狀态和節點。

對于疊代函數,可以判斷其是否存在周期,以及求出其最小正周期。

五、相關算法

雖然Floyd判圈算法已經達到了線性時間複雜度和常數空間複雜度,但是Brent判圈算法将減小時間複雜度的常數系數,平均消耗時間比Floyd判圈算法少36%。

Bruent算法描述:

Bruent算法裡有運動的兔子和靜止的烏龜。這裡的烏龜在兔子行進步數到達step_limit時,會傳送到兔子的位置,同時将兔子的行進步數重置為0,同時提高step_limit為原來的兩倍。

烏龜和兔子都從名單的頂部開始。兔子每疊代一步。如果是和固定的烏龜一樣的位置,那顯然是一個循環。如果到達清單的末尾,則沒有循環。

為什麼要移動烏龜呢?如果一隻兔子被卡在一個循環中,沒有遇到烏龜,它将永遠循環,是以需要将烏龜在一定步數後傳送到兔子位置。

為什麼每次要花兩倍的時間?最終,傳送之間的時間長度将比回路的長度更長,是以當兔子完成一圈時,烏龜将在那裡等待兔子。

Bruent算法的僞代碼描述:

六、相關題目摘錄

Linked List Cycle

問題描述:

Floyd判圈算法 Floyd Cycle Detection Algorithm

問題求解:

Linked List Cycle II

Floyd判圈算法 Floyd Cycle Detection Algorithm

Happy Number

Floyd判圈算法 Floyd Cycle Detection Algorithm

疊代會生成環,非happy number的環中顯然是不可能存在1的,是以如果落入了環中,那麼就不可能算得1,否則兩者在運算到1後相等。

Find the Duplicate Number

Floyd判圈算法 Floyd Cycle Detection Algorithm

經典的判圈算法的題目。

繼續閱讀