Floyd判圈算法(判斷鏈表是否含環)
阿新 • • 發佈:2018-10-25
鏈表是否有環 als 龜兔賽跑算法 code 狀態 如果 inline span -s
等價於判斷是否有環。用Floyd算法判斷是否有環。
Floyd判圈算法
簡介
Floyd判圈算法,也稱龜兔賽跑算法,可用於判斷鏈表、叠代函數、有限狀態機是否有環。如果有,找出環的起點和大小。時間復雜度O(n),空間復雜度O(1)。
可以先思考一下,假設有一個圓形的跑道周長為\(C\),A和B從同一個起點,分別以\(v\)和\(2v\)的速度同向出發,可以知道,因為B比A跑得快而且跑道是環形的,所以接下來一定存在某一時刻,B和A相遇,這時候,B跑過的總距離\(S_B\)減去A跑的總距離\(S_A\)一定是\(C\)的整數倍。即: \(S_B-S_A = k*C, k=1,2,...\)。
算法思路
在判斷鏈表是否有環的問題中,可以使用Floyd算法來判斷。
使用2個指針,一個快(fast)一個慢(slow),初始化兩個指針在起始位置。每次fast向前走兩步,slow向前走一步。若fast到達了終點,則證明鏈表中有環。若fast和slow再次相遇,則說明鏈表中含環。
例題
leetcode202. Happy Number
題意:
判斷某個數字是不是happy number.
happy number滿足一下幾點:
以任意正整數開頭,用它各個位置上數字的平方和生成一個新的數字。
對於該新的數字,重復上述步驟,如果最後生成的數字是1。則原始數字是happy number。
解法一:
借助set容器,每次生成的數字放入set中,如果出現了重復,即說明出現了循環,則該數字不是happy number.
解法二:
等價於判斷是否有環。用Floyd算法判斷是否有環。
解法二代碼:
class Solution{ public: int cal(int n){ string s=to_string(n); int sum=0; for(char num:s){ sum += (num-‘0‘)*(num-‘0‘); } // cout<<"sum: "<<sum<<endl; return sum; } bool isHappy(int n){ int slow=n, fast=n;// 初始化 while(slow!=1 && fast!=1){ slow = cal(slow);// 走一步 if(slow==1) return true; fast = cal(cal(fast));//走兩步 if(slow==fast) return false; }; return true; } };
Floyd判圈算法(判斷鏈表是否含環)