1. 程式人生 > >Floyd判圈演算法(龜兔賽跑演算法, Floyd's cycle detection)及其證明

Floyd判圈演算法(龜兔賽跑演算法, Floyd's cycle detection)及其證明

問題:如何檢測一個連結串列是否有環(迴圈節),如果有,那麼如何確定環的起點以及環的長度。
空間要求:不能儲存所經過的的每一個點。
舉例:x0=1,xi+1=f(xi),求迴圈節的起始位置以及迴圈節的長度


求解步驟:

1.判斷是否有環

fig01|center
使用兩個指標slow和fast。兩個指標開始時均在頭節點處(S點),slow指標(龜)一次向後移動一個一步,fast指標(兔)一次向後移動兩步。若存在環,則slow和fast必能相遇;反之若slow到達連結串列尾時兩個指標仍不能相遇,則不存在環。
證明
設頭節點S與迴圈節起始點A之間舉例|SA|

=m。兩個指標在B點相遇,|AB|=n。可知環中的點滿足xi=xi+kl,其中l為迴圈節的長度,也就是說fast比slow多走了整數圈。當i=kl時,滿足xi=x2i,這樣的i一定存在,得證。

2.計算環的長度

這一步比較簡單,讓其中一個指標停在B不動,另一個一步一步向前走並記錄步數,再次相遇時步數即為環的長度。

3.尋找環的起點

其中一個指標在B不動,另一個放到起點S,兩個指標同時一步一步移動,則兩指標將會在迴圈節的起點相遇。
證明
B點的下標 i=kll的整數倍。當放到S處的指標移動m到達A時,放在

B的指標移動到i+m=kl+m處,於是兩個指標相遇。

程式碼如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e7;
int f(int x)
{
    int res = 0;
    //此處填寫遞推式,使其走到下一步
    return res;
}
//ori為起點處的值,len為迴圈節長度,id為迴圈節起始處座標,val為迴圈節起始處的值
bool FloydCycle(int ori, int &len, int &id,  int
&val)//有環返回true,無環返回false { int slow, fast;//慢指標和快指標 slow = f(ori);//快指標的移動速度是慢指標的2倍 fast = f(f(ori)); int cnt = 1; while(slow != fast && cnt <= maxn)//maxn為連結串列尾節點 { //快指標的移動速度是慢指標的2倍 slow = f(slow); fast = f(f(fast)); cnt++; } if(slow != fast) return false;//無環 len = 1;//環的長度 slow = f(slow); while(slow != fast) { slow = f(slow); len++; } id = 0; slow = 1; while(slow != fast) { slow = f(slow); fast = f(fast); id++; } val = slow; return true; }

相關推薦

Floyd演算法龜兔賽跑演算法, Floyd's cycle detection及其證明

問題:如何檢測一個連結串列是否有環(迴圈節),如果有,那麼如何確定環的起點以及環的長度。 空間要求:不能儲存所經過的的每一個點。 舉例:x0=1x0=1,xi+1=f(xi)xi+1=f(xi),求

Floyd演算法龜兔賽跑演算法

一、演算法簡述 Floyd判圈演算法(Floyd Cycle Detection Algorithm),又稱龜兔賽跑演算法(Tortoise and Hare Algorithm),是一個可以在有限

Floyd演算法龜兔賽跑演算法記錄

前言 這是在做 142. 環形連結串列 II 時看到的演算法,在這裡記錄,方便以後複習和學習; Floyd判圈演算法(Floyd Cycle Detection Algorithm),又稱龜兔賽跑演算法(Tortoise and Hare Algori

龜兔賽跑演算法Floyd演算法

參考資料: 1. 維基百科 https://zh.wikipedia.org/w/index.php?title=Floyd判圈演算法&redirect=no 2. http://blog.c

Floyd演算法及其證明

Floyd判圈演算法(龜兔賽跑演算法)可用於判定連結串列、迭代函式、有限狀態機是否有環。如果有環,可以找出環的起點和大小。 首先,讓我們確認一個事實:兩個人在環形跑道上同向而行,一前一後,速度不等,則快的那個一定能追上慢的那個。 設兩人相距x,跑道周長為C,

Floyd演算法(判斷是否有環)

用於判斷是否存在環,求解環的起點,求解環的周長 時間複雜度:O(n) 演算法原理:龜兔解法的基本思想可以用我們跑步的例子來解釋,如果兩個人同時出發,如果賽道有環,那麼快的一方總能追上慢的一方。進一步想,追上時快的一方肯定比慢的一方多跑了幾圈,即多跑的路的長度是圈的長度的

11549 Calculator Conundrum (迴圈節)(Floyd演算法,快慢指標)

Alice got a hold of an old calculator that can display n digits. She was bored enough to come up with the following time waster.

Floyd演算法 leetcode 202題Happy Number

今天,日常刷leetcode,遇到202問題如下:Write an algorithm to determine if a number is "happy".A happy number is a number defined by the following proces

Cycle detection——Floyd演算法

Cycle detection 作者:money 標籤:leetcode,algorithm,Floyd’s cycle-finding algorithm,floyd判圈演算法 問題描述 對於一個函式f,他能將有限集合S對映到自身,對於起始數值X0

Floyd算法(判斷鏈表是否含環)

鏈表是否有環 als 龜兔賽跑算法 code 狀態 如果 inline span -s Floyd判圈算法 簡介 Floyd判圈算法,也稱龜兔賽跑算法,可用於判斷鏈表、叠代函數、有限狀態機是否有環。如果有,找出環的起點和大小。時間復雜度O(n),空間復雜度O(1)。 可以先

決策樹演算法ID3,C4.5,CART

ID3,C4.5,CART是是決策樹的核心演算法。它們都由特徵選擇,樹的生成,剪枝組成。但ID3和C4.5用於分類,CART可用於分類與迴歸。 1.ID3演算法 ID3演算法遞迴地構建決策樹,從根節點開始,對所有特徵計算資訊增益,選擇資訊增益最大的特徵作為節點的特徵,由該特徵的不同取值建

小白python學習——機器學習篇——k-近鄰演算法KNN演算法

一、演算法理解 一般給你一資料集,作為該題目的資料(一個矩陣,每一行是所有特徵),而且每一組資料都是分了類,然後給你一個數據,讓這個你預測這組資料屬於什麼類別。你需要對資料集進行處理,如:歸一化數值。處理後可以用matplotlib繪製出影象,一般選兩個特徵繪製x,y軸,然後核心是計算出預測點到

(排序演算法)linux c語言實現選擇排序演算法氣泡排序的略微改進版

 快速排序演算法和氣泡排序演算法是差不多的,都是要兩層迴圈,外迴圈是要比較的個數,其實就是元素的個數,內迴圈就是外層那個標記和其他的比較大小, 氣泡排序是相鄰的兩個,兩兩比較,最後交換出一個最大或者最小值, 快速排序是在氣泡排序的基礎上,找出那個最小的或者最大的,但是不是直接交換,

樹的前、中、後序遍歷演算法遞迴與非遞迴、層序遍歷

二叉樹層次遍歷 非遞迴 void LevelOrder(Tree* T) { if(T == nullptr) return ; queue<Tree *> myqueue; myqueue.push(T); while(!myqueu

《資料結構與演算法》之排序演算法插入排序、希爾排序

3、插入排序 插入排序的基本操作就是將一個數據插入到已經排好序的有序資料中,從而得到一個新的、個數加一的有序資料,演算法適用於少量資料的排序,時間複雜度為O(n^2),是穩定的排序方法。插入演算法把要排序的陣列分成兩部分:第一部分包含了這個陣列的所有元素,但將最後一個元素除外(讓陣列多一個空間才

墨卡託切片地圖獲取圖層的Resulations簡易演算法在知道地圖原點座標位置

    <TileMatrixSet>             <ows:Identifier>EPSG:900913</ows:Identifier>     &

反向傳播演算法BP演算法

BP演算法(即反向傳播演算法),適合於多層神經元網路的一種學習演算法,它建立在梯度下降法的基礎上。BP網路的輸入輸出關係實質上是一種對映關係:一個n輸入m輸出的BP神經網路所完成的功能是從n維歐氏空間向m維歐氏空間中一有限域的連續對映,這一對映具有高度非線性。它的資訊處理能力來源於簡單非線性函式的多

排序演算法天勤資料結構高分筆記

排序演算法 直接插入排序演算法:每趟將一個待排序的關鍵字按照其值的大小插入到已經排好的部分有序序列的適當位置上,直到所有待排關鍵字都被插入到有序序列中為止 void InsertSort(int R[], int n)    //代拍關鍵字儲存在R[]中,預設為

Kruskal演算法題目還是:還是暢通工程

那還是先把題目丟出來,是HDU上的一道題   暢通工程   Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su

累加和校驗演算法CheckSum演算法

因為外界總會對電路存在或多或少的干擾,對於數字訊號,很可能導致傳輸的資料出現千差萬別。對於很多需要傳輸資料的場合,尤其是一些資料可能會影響一些硬體的動作(諸如嵌入式的一些裝置、機器人等),錯誤的資料可能會帶來一些隱性風險,想想都可怕。 由於本人是嵌入式相關領域的,平時玩的都是微控制器,當然微