LeetCode 141 環形鍊錶

2021-09-25 02:46:21 字數 2619 閱讀 6875

給定乙個鍊錶,判斷鍊錶中是否有環。

為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鍊錶中沒有環。

示例 1:

輸入:head = [3,2,0,-4], pos = 1

輸出:true

解釋:鍊錶中有乙個環,其尾部連線到第二個節點。

示例 2:

輸入:head = [1,2], pos = 0

輸出:true

解釋:鍊錶中有乙個環,其尾部連線到第乙個節點。

示例 3:

輸入:head = [1], pos = -1

輸出:false

解釋:鍊錶中沒有環。

高階:你能用 o(1)(即,常量)記憶體解決此問題嗎?

方法一:使用快慢指標

思路

想象一下,兩名運動員以不同的速度在環形賽道上跑步會發生什麼?

演算法

通過使用具有不同速度 的快、慢兩個指標遍歷鍊錶,空間複雜度可以被降低至 o(1)。慢指標每次移動一步,而快指標每次移動兩步。

如果列表中不存在環,最終快指標將會最先到達尾部,此時我們可以返回 false。

現在考慮乙個環形鍊錶,把慢指標和快指標想象成兩個在環形賽道上跑步的運動員(分別稱之為慢跑者與快跑者)。而快跑者最終一定會追上慢跑者。這是為什麼呢?考慮下面這種情況(記作情況 a)- 假如快跑者只落後慢跑者一步,在下一次迭代中,它們就會分別跑了一步或兩步並相遇。

其他情況又會怎樣呢?例如,我們沒有考慮快跑者在慢跑者之後兩步或三步的情況。但其實不難想到,因為在下一次或者下下次迭代後,又會變成上面提到的情況 a。

/**

* definition for singly-linked list.

* class listnode

* }*/public class solution

//使用快、慢指標判斷是否存在環

//快指標在前,慢指標在後,如果鍊錶中不存在環,則快指標永遠在慢指標前面,且最終先到達尾結點,即先為null值

//如果快指標經過環後,追上慢指標,即快指標和慢指標相等(指向同一結點),則說明鍊錶中存在環

listnode slow = head;

listnode fast = head.next;

while(fast != slow) else

}//跳出while迴圈條件,則說明fast指標追上了slow指標,鍊錶中存在環

return true;}}

複雜度分析鍊錶中不存在環:快指標將會首先到達尾部,其時間取決於列表的長度,也就是 o(n)

鍊錶中存在環:

我們將慢指標的移動過程劃分為兩個階段:非環部分與環形部分:

慢指標在走完非環部分階段後將進入環形部分:此時,快指標已經進入環中 迭代次數 = 非環部分長度 = n

兩個指標都在環形區域中:考慮兩個在環形賽道上的運動員 - 快跑者每次移動兩步而慢跑者每次只移動一步。其速度的差值為 1,因此需要經過

二者之間距離 / 速度差值

次迴圈後,快跑者可以追上慢跑者。這個距離幾乎就是 "環形部分長度 k " 且速度差值為 1,我們得出這樣的結論:迭代次數 = 近似於 「環形部分長度 k」。

因此,在最糟糕的情形下,時間複雜度為 o(n+k),也就是 o(n)。

方法二:雜湊表

方法一:雜湊表

思路

我們可以通過檢查乙個結點此前是否被訪問過來判斷鍊錶是否為環形鍊錶。常用的方法是使用雜湊表。

演算法

我們遍歷所有結點並在雜湊表中儲存每個結點的引用(或記憶體位址)。如果當前結點為空結點 null(即已檢測到鍊錶尾部的下乙個結點),那麼我們已經遍歷完整個鍊錶,並且該鍊錶不是環形鍊錶。如果當前結點的引用已經存在於雜湊表中,那麼返回 true(即該鍊錶為環形鍊錶)。

public boolean hascycle(listnode head)  else 

head = head.next;

}return false;

}

複雜度分析

時間複雜度:o(n),對於含有 n 個元素的鍊錶,我們訪問每個元素最多一次。新增乙個結點到雜湊表中只需要花費 o(1) 的時間。

空間複雜度:o(n),空間取決於新增到雜湊表中的元素數目,最多可以新增 n 個元素。

方法三:借助陣列,但是空間複雜度o(n)

類似於方法二,對已經訪問過的結點位置做標記

leetcode141 環形鍊錶

給定乙個鍊錶,判斷鍊錶中是否有環。高階 你能否不使用額外空間解決此題?思路 剛開始想著讓他迴圈下去,直到和頭結點相同的時候,就返回 true,否則就返回 false,但還是 too young too 實際上還是設定兩個指標,乙個快指標和乙個慢指標,只要是在環裡面,總會相遇的,就可 return t...

LeetCode141 環形鍊錶

題目描述 給定乙個鍊錶,判斷鍊錶中是否有環。高階 你能否不使用額外空間解決此題?演算法描述 1.使用兩個快慢指標遍歷鍊錶。slow每次走一步,fast每次走兩步。fast走到鍊錶尾部無環,slow與fast重疊則有環。2.若鍊錶的起始位置等於環的起始位置 slow走一圈回到起始位置,fast剛好走了...

LeetCode141環形鍊錶

給定乙個鍊錶,判斷鍊錶中是否有環。設定兩個指標,乙個fast乙個slow,遍歷整個列表,若達到表尾時仍未出現指標相等則鍊錶無環。c語言版 definition for singly linked list.struct listnode bool hascycle struct listnode h...