1. 程式人生 > >Floyd判圈演算法(龜兔賽跑演算法)記錄

Floyd判圈演算法(龜兔賽跑演算法)記錄

前言

這是在做 142. 環形連結串列 II 時看到的演算法,在這裡記錄,方便以後複習和學習;

Floyd判圈演算法(Floyd Cycle Detection Algorithm),又稱龜兔賽跑演算法(Tortoise and Hare Algorithm),是一個可以在有限狀態機、迭代函式或者連結串列上判斷是否存在環,以及判斷環的起點與長度的演算法。 – 百度百科

作用:判定連結串列中是否有環存在以及一些其他的作用,下面會具體說到

基本思想: 既然它的外號叫做“龜兔賽跑演算法”,那肯定就要體現出烏龜和兔子的作用了,即一個跑得慢一個跑得快,如果有環的話,那麼,兔子肯定是能追上烏龜的,而且追上的時候兔子多跑的路的長度是圈的長度的倍數。以下就用pH

指標表示兔子,一次能跑兩步(沒病走兩步……),pT指的是烏龜,一次能跑一步;

例子

這裡就以 142. 環形連結串列 II 這題來記錄一下:
題目說道:

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Note: Do not modify the linked list.

也就是說,如果連結串列有環存在的話,就要返回第一個入環的節點,比如下圖:
這裡寫圖片描述

就應該返回的是2這個節點;而要找到這個入環節點,首先就要先判斷是否有環,通過自己實驗可以知道,當有環存在的時候,當兔子追到烏龜(在一起了= =|| )的時候:
這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

從追到的這個地方開始,比如這裡是節點4,從節點3到4的這個不考慮,然後從1和節點4開始往下遍歷相同的步數,當遍歷到的是同一個時即為入環結點:
這裡寫圖片描述

則根據龜兔賽跑演算法的思想,可以有如下的程式碼:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // 龜兔賽跑演算法
        ListNode* pH = head; // 兔子
        ListNode* pT = head; // 烏龜

        while
(pH != NULL && pH->next != NULL && pH->next->next != NULL){ // 這裡需要判斷pH以及pH->next->next是否為NULL,但是如果pH->nextNULL的話就會有空指標異常,所以還要加一個pH->next是否為NULL的判斷 pT = pT->next; pH = pH->next->next; if(pT == pH){ // 有環,則接下來從龜兔相遇的地方開始作為head2 // 將tempHead和head2同時移動相同的距離,相等的地方即為入環結點 ListNode* head2 = pT; ListNode* tempHead = head; while(tempHead != head2){ tempHead = tempHead->next; head2 = head2->next; } return head2; } } return NULL; } };

總結

  1. 判斷是否有環:只需要看pH和pT是否會相遇(遍歷到同一個結點)即可,相遇的話就說明 有環;
  2. 確定入環結點:如上所述,這裡不再贅述;
  3. 求環的長度:(1) 變數i記錄從龜兔相遇的地方head2開始與head同時移動,多少次才相遇,結果再 +1,即為環形連結串列的結點個數;或者(2)相遇的時候,一定已經在環上了,然後兔子和烏龜只要再次在環上接著跑,再次相遇的時候,跑的快的那個人就比跑的慢的人整整多跑了一圈,所以環的長度也就出來了;

相關推薦

Floyd演算法龜兔賽跑演算法

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

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

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

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

為什麼我要放棄javaScript資料結構與演算法第一章—— JavaScript簡介

資料結構與演算法一直是我算比較薄弱的地方,希望通過閱讀《javaScript資料結構與演算法》可以有所改變,我相信接下來的記錄不單單對於我自己有幫助,也可以幫助到一些這方面的小白,接下來讓我們一起學習。 第一章 JavaScript簡介 眾所周知,JavaScript是一門非常強大的程式語言,不僅可以用於

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

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

機器學習實戰Apriori演算法關聯分析

目錄 0. 前言 1. Apriori 演算法尋找頻繁項集 2. 從頻繁項集中挖掘關聯規則 3. 實戰案例 3.1. apriori演算法發現頻繁項集和關聯規則 學習完機器學習實戰的Apriori,簡單的做個筆記。文中部分描述屬於

基於分解的多目標進化演算法MOEA/D

目錄 1、MOEA/D的特點 2、 MOEA/D的分解策略 3、MOEA/D的流程 基於分解的多目標進化演算法(Multi-objectiveEvolutionary Algorithm Based on Decomposition, MOEA/D)將多目標優化問題被轉

經典排序演算法Java版

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

關於離散小波框架變換以及多孔演算法a trous的學習感悟

最近學習小波變換與非抽取的小波變換,尤其是非抽取的小波變換,在學習感覺非常困惑,最後也得出一點感悟,不知是否正確,僅供參考,相互學習! 首先,我是在文獻[1]瞭解到離散小波框架的,在文獻[2]瞭解到多孔演算法的。學習過程中,查看了很多圖書以及網上的資料,講得都很抽象,部落格[3]對我的幫助很大。

LL(0)語法分析演算法完整版 ----編譯原理試驗

                                          &

常用演算法Java表述

 氣泡排序(Bubble Sort) 氣泡排序:一種交換排序,它的基本思想是:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。穩定排序演算法 時間複雜度 O(n2),裡層迴圈每趟比較第 j 項和第 j+1項,如果前項大於後項,則發生交換。缺點是每次比較後都可能發生交換,

深度學習中的優化演算法待更

    優化演算法可以使得神經網路執行的速度大大加快,機器學習的應用是一個高度依賴經驗的過程,伴隨著大量迭代的過程,需要訓練諸多的模型來找到最合適的那一個。其中的一個難點在於,深度學習沒有在大資料領域發揮最大的效果,我們可以利用一個巨大的資料集來訓練神經網路,

反向傳播演算法BP演算法

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

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

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