brent演算法為什麼比floyd演算法快

2021-09-10 03:12:56 字數 2737 閱讀 8970

問題:用乙個演算法,實現判斷是否會出現如下的有環的單鏈表

以龜兔賽跑來解釋這一演算法,尋找單鏈表中是否含有乙個圈。

一、思想:

龜和兔子同時出發,龜走一步,兔子走兩步,兔子比龜快,所以兔子一定可以追上龜,就好像在環形跑道中跑的快的運動員會從後面超過跑得慢的運動員。

//頭指標給龜和兔,初始化

tortoise = top

hare = top

forever:

//兔子走兩步

if hare == end :

return

'no loop found'

hare = hare.next

if hare == end :

return

'no loop found'

hare = hare.next

//烏龜走一步

tortoise = tortoise.next

//龜兔相遇則有環

if hare == tortoise:

return

'loop found'

二、時間複雜度分析:

令x是出發點到環的起點的距離,y是環的長度。烏龜最多走x+y步,兔子最多2(x+y)步。

下面給出證明:

(1)烏龜只能在環裡走一圈

假設:鍊錶的起點距離環的起點x長度,此時的烏龜在環裡,距離環的起點y1長度,由題目可知,當龜兔的距離等於y時,龜兔相遇,即龜兔距離差為y。

因為兔子的速度是烏龜的兩倍,所以龜兔的差距為x+y1,環的長度為y,故當烏龜走了一圈以後,龜兔之間的差距為x+y>=y。所以在烏龜還沒走完一圈,就會產生乙個臨界點,此時的龜兔恰好相遇,也就是在某一點,x+y1* ==y。

(2)由1的證明結論可知,烏龜最多在環裡面走一圈,所走的長度為x+y1*(y1* 一、思想:

龜和兔子同時出發,龜不動,兔子走1步,第二輪,烏龜跳到兔子的位置,兔子走兩步,第三輪。。。。第n輪,烏龜跳到兔子的位置,兔子走2^n步。

//初始化,兔和龜都在鍊錶的頭部

turtle = top

rabbit = top

steps_taken =

0//兔子每次迭代走了幾步

step_limit =

2//兔子每次迭代做多可以走幾步

forever:

//如果發現兔子到頭了,結束迴圈

if rabbit == end:

return

'no loop found'

//兔子移動一步

rabbit = rabbit.next

steps_taken +=1

//兔子和烏龜相遇,則表示有環

if rabbit == turtle:

return

'loop found'

//兔子這個週期移動的步數到達上限

if steps_taken == step_limit:

steps_taken =

0//steps_taken初始化為0

step_limit *=2

//step_limit表示下次迭代的上限翻倍

// teleport the turtle

turtle = rabbit //讓烏龜跳到兔子的位置上

二、時間複雜度分析:

證明:brent演算法中,烏龜最多在環中走一圈。

證明過程類似死於floyd的證明方式,當烏龜在環內部走了y2長度時,兔子距離烏龜為:

烏龜走了:

1+2+4…+ 2^n == x+y2

下一次兔子行走的距離為: 2^(n+1),又

1+2+4…+ 2^n == 2^(n+1) - 1

所以龜兔距離x+y2+1

綜上所述:每一輪迭代,龜走到了x+y2的地方,兔子從x+y2出發,走到2(x+y2)+1處停止,進行下一輪迭代,兔子的速度比烏龜快一倍+1,故在環中,烏龜走到x+y之前,兔子早就與其相遇,臨界位置為y2* ,此時烏龜走了x+y2* ,兔子走了x+y2* +y(此時的y == x+y2*+1)。

1.當採用floyd演算法時,烏龜走x+y1個距離,此時龜兔距離差為x+y1

2.當採用brent演算法時,烏龜走x+y2個距離,龜兔差距x+y2+1

當x,y2和y1較大時,迭代過程中,floyd演算法要移動指標x+y1* +2(x+y1* )次(烏龜移動指標+兔子移動指標),大約是

o(3*(x+y))

而brent演算法移動2(x+y2*) + n(n輪迭代,每次兔子的指標都要賦值給烏龜),明顯時間複雜度上brent演算法更有優勢而且大約是x+y1* +2(x+y1* ),大約是

o(2*(x+y))

明顯,brent演算法時間複雜度低,大約快了1/3,當然,如果加上式子中n(n = log2(x+y))對結果的影響,可能提公升不到1/3.

為什麼 比list()更快?

我最近比較了和list 的處理速度,並且驚訝地發現執行速度比list 快三倍以上。我跑了相同的測試與 和dict 結果幾乎相同 和 兩個花了大約0.128sec 百萬次,而list 和dict 大約花費每個0.428sec 萬次。後來我查了查原因,得到的結論如下 list 需要全域性查詢和函式呼叫,...

為什麼get比post更快

get和post在面試過程中一般都會問到,一般的區別 1.post更安全 不會作為url的一部分,不會被快取 儲存在伺服器日誌 以及瀏覽器瀏覽記錄中 2.post傳送的資料量更大 get有url長度限制 3.post能傳送更多的資料型別 get只能傳送ascii字元 4.post比get慢 我相信不...

java為什麼 foreach比for效率高

1 for是使用下標 偏移量 定位的.2 foreach應該是使用類似迴圈子的機構 3 對隨機訪問效率高的arraylist.使用下標訪問效率本身很高.foreach內部的迴圈子直接封裝下標,自己實現的for比foreach更直接,效率稍高些,但差別不會太大,仍然在乙個數量級上。4 如果使用插入和刪...