環形鍊錶專題

2021-10-23 21:00:51 字數 3465 閱讀 2813

最近在刷leetcode的題,對環形鍊錶方面的題做個總結

**:二、帶環鍊錶入口

環形鍊錶-力扣(leetcode)

解法一:快慢指標

我們定義兩個指標,初始位置都放在頭節點的地方,然後快慢指標一起走,快指標一次走兩步(需要注意邊界條件),慢指標一次走一步,如果快指標走到nullptr,該鍊錶就不帶環;如果快慢指標相遇,該鍊錶就帶環。

為什麼這個辦法可以解決,我們是需要給出理論依據的,先舉個最常見的例子,兩個人在操場跑步,乙個人的速度是另乙個人的兩倍,如果跑的快的人追上跑的慢的人,那麼快的人必然超過慢的人一圈。那麼在鍊錶中,也是一樣的:

如果使用快慢指標,他們會在4的位置相遇,此時就可以返回了。

我們給出**:

// 快慢指標

class solution

listnode* fast = head;

listnode* slow = head;

dowhile(slow != fast);

return true;}};

複雜度分析:

空間複雜度o(1)

附上一張通過的圖:

解法二:雜湊表/map

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

// map

class solution

mapkey;

listnode* pcur = head;

while(pcur)

else

pcur = pcur->next;

}return false;}};

複雜度分析:

map可以解決,unordered_map當然也可以解決

class solution 

unordered_mapkey;

listnode* pcur = head;

while(pcur)

else

pcur = pcur->next;

}return false;}};

至於setunordered_set,自己試試就知道了。

複雜度分析:

附圖:

解法三: 非常規做法

堆位址從低到高,leetcode的鍊錶記憶體是順序申請的,如果有環,head->next一定小於head

附上**:

環形鍊錶ii-力扣(leetcode)

解法一:快慢指標

上一道題目,已經詳細講解了快慢指標判斷鍊錶帶環,其實我們可以利用快慢指標相遇的節點,我們需要發覺一下這個點的魅力。

我們把節點增多幾個,節點太少不好觀察:

我們假設煉表頭結點到環入口位置距離為a,環的入口與相遇節點位置距離為b,環的長度為r,我們計算快慢指標所走過的距離:

d(fast) = a + b + n * r

d(slow) = a + b

快指標的速度是慢指標的兩倍,相同時間,快指標所走過的路程應該是慢指標所走過路程的兩倍,於是:

d(fast) = 2 * d(slow)

所以有:a = n * r - b

當n = 1時,也就是快指標走了一圈之後,在第二圈的時候遇見了慢指標,a = r - b

我們可以發現,a是鍊錶的表頭到環的入口點的位置,(r - b)是相遇點到環入口點的位置。

但是我們需要考慮一種特殊情況,鍊錶是首尾相連的:

我們可以發現,如果鍊錶的表頭就是入口點,使用快慢指標的時候,因為快指標是慢指標的速度的2倍,所以它們一定是慢指標走了一圈,快指標走了兩圈的時候相遇,就是在環的入口點相遇。

附上**:

class solution 

listnode *slowptr = head;

listnode *fastptr = head;

/** 快慢指標

* 如果快指標追上慢指標,說明鍊錶帶環

* 並且快慢指標相遇的點一定是換上的一點

*/do

while(slowptr != fastptr);

/** 讓慢指標回到頭節點位置

* 然後快慢指標一起走

* 再次相遇的地方必然是環的入口

* 原因:

*/slowptr = head;

while(slowptr != fastptr)

return slowptr; }};

附上圖:

解法二:非常規做法

堆的位址從低到高,leetcode的鍊錶記憶體是順序申請的,如果有環,head->next一定小於head

class solution 

head = head->next;

}return nullptr;}};

附圖:

鍊錶專題2 環形鍊錶 II

給定乙個鍊錶,判斷鍊錶中是否有環。為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置 索引從 0 開始 如果 pos 是 1,則在該鍊錶中沒有環。示例 1 輸入 head 3,2,0,4 pos 1 輸出 tail connects to node index 1 解釋 鍊...

鍊錶 環形鍊錶

環形鍊錶也叫迴圈鍊錶 可以是雙鏈表 也可以是單鏈表 操作原理和單鏈表差不多,只是最後乙個節點不在指向空 null 而是頭 head 這裡以單鏈表舉例 description 環形鍊錶 author lzq date 2018 11 3 20 46 version 1.0 public class a...

鍊錶 環形鍊錶

題目描述 給定乙個鍊錶,返回鍊錶開始入環的第乙個節點。如果鍊錶無環,則返回 null。為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置 索引從 0 開始 如果 pos 是 1,則在該鍊錶中沒有環。注意,pos 僅僅是用於標識環的情況,並不會作為引數傳遞到函式中。說明 不允...