旋轉鏈結串列 | Medium | LeetCode#61. Rotate List
題目敘述

- 題目難度:
Medium - 題目描述: 給定一個 Linked List 的
head,選轉整個 Listk次後回傳新的List head
解法
一開始的想法
看題目給的範例測資,可以知道所謂旋轉就是尾端的 node 插入到 List 前端作為新的 head,而這個操作要進行
k次,一開始的想法就是很直觀, 找到尾端節點,插入到首端,然後遞迴操作
先前的解法
1 | /** |
這裡的想法就是先宣告兩個指標 last 跟 prev,last 用於指向Linked List 的最後一個節點,而 prev 用於紀錄 last 的前一個元素,也就代表新的尾端元素。接著就將 last 指向到 head,然後由於 prev 會是新的末端節點,因此需要指向 nullptr,然後就遞迴呼叫 rotateRight 本身,最後一旦 k 減為0,就回傳新的 head。
這種做法會導致每一次的遞迴呼叫都會建立
prev節點,會大量消耗記憶體,出現 Memory Limit Exceeded
更好的做法
1 | /** |
這裡改用 Iteration 的方式來實作,首先原先的 last 在迭代的時候同時也紀錄 list 的長度,接著將 last 指向 head 作為新的 head。 k 代表要選轉多少次,但這個數字可能會遠大於 linked list 長度 length,所以可以透過 k % length 來先找到最終的 head 會輪到哪個節點。
知道是哪個節點後,還需要知道從該節點 走到該節點走到末端節點要走幾步,所以透過 length - k 來得到 countToNewHead,之後定義一個新的 newTail 來獲取當前 Linked List 的倒數第二個節點,這樣他的 next 就會是新的head newHead,之後將 newTail 指向到 nullptr 斷開環形結構後就可以直接回傳 newHead 了。
執行結果

複雜度
時間複雜度
| 方法 | 時間複雜度 | 分析簡述 |
|---|---|---|
| Recursion | $O(k \times n)$ | 每次遞歸都會遍歷整個鏈表找到最後一個節點,總共執行 $k$ 次,因此時間複雜度為 $O(k \times n)$ |
| Iteration | $O(n)$ | 計算鏈表長度需遍歷一次,再執行一次遍歷找到新頭節點,因此總共遍歷 2 次,時間複雜度為 $O(n)$ |
空間複雜度
| 方法 | 空間複雜度 | 分析簡述 |
|---|---|---|
| Recursion | $O(k)$ | 每次遞歸會佔用棧空間,深度為 $k$,因此空間複雜度為 $O(k)$ |
| Iteration | $O(1)$ | 僅使用少量指針變數進行操作,不需要額外的空間,空間複雜度為 $O(1)$ |
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Kevin Liu's 部落格 || Technical || Travel!
評論










