問題:用乙個演算法,實現判斷是否會出現如下的有環的單鏈表
以龜兔賽跑來解釋這一演算法,尋找單鏈表中是否含有乙個圈。
一、思想:
龜和兔子同時出發,龜走一步,兔子走兩步,兔子比龜快,所以兔子一定可以追上龜,就好像在環形跑道中跑的快的運動員會從後面超過跑得慢的運動員。
//頭指標給龜和兔,初始化
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長度時,兔子距離烏龜為:
烏龜走了:所以龜兔距離x+y2+11+2+4…+ 2^n == x+y2
下一次兔子行走的距離為: 2^(n+1),又
1+2+4…+ 2^n == 2^(n+1) - 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 如果使用插入和刪...