LeetCode #92 Reverse Linked List II - 刷題之旅
1 題目描述
簡單來說,就是在指定的位置 m 到 n 之間,將鍊錶進行反轉。
注意的是,題目要 one pass 是指只能遍歷一次鍊錶,不能多次遍歷。
2 解法
2.1 我的解法
我的想法很簡單
- 先建立一個字典,紀錄 key = index, value = node
- 你會發現 left 到 right 之間的反轉,從 left 開始,left 應該改成 right 的值,right 應該改成 left 的值,直到 left 跟 right 相遇。
- 何時該停呢?當 left >= 原本的 right 時,就停止。
大概是這種感覺
1 | class Solution: |
2.2 雙指針解法
這個做法真的是從來沒想過,但是很巧妙,而且只需要遍歷一次鍊錶,就可以完成反轉。超級厲害!
他的概念是這樣的:
- 先找到
pre
這個節點- 怎麼找到
pre
? 這個節點是 left 的前一個節點,也就是left - 1
,之後就都固定pre
不動。 - 為什麼需要? 因為
pre
要負責更新pre.next
為反轉後的第一個節點。
- 怎麼找到
- 再來就是
cur
這個節點,- 怎麼找到
cur
? 最一開始,cur
是pre.next
,之後就固定cur
不動。 - 為什麼需要? 因為
cur
要負責更新cur.next
為next.next
這個節點,往前移動。
- 怎麼找到
- 最後是
next
這個節點- 怎麼找到
next
? 最一開始,next
是cur.next
,之後就固定next
不動。 - 為什麼需要? 因為
next
要負責更新next.next
為cur
這個節點,往前移動。
- 怎麼找到
大概是這種感覺,你會發現 next 會被塞到 pre.next 這個位置,而 cur 就一直往前移動
1 | class Solution: |
3 總結
這題不難理解,凡是想要從 O(n^2) 變成 O(n) 可以使用 HashMap,所以我一開始就建立字典記錄所有的位置。但是後來看到雙指針解法,真的是很厲害,腦袋到底怎麼想到的啊!
如果今天要有順序的進行反轉或是整批的改變位置移動,雙指針會是一個Linked List的重點。想像有兩個指針,一個指針cur
慢往前,另一個指針會是目標節點target
(在這裡是next
),target
會串到想要放的目標 location(在這裡是pre.next
),cur
會一直往前移動(cur.next
變成 pre.next
),直到達到目標節點,這樣就可以完成操作。
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Shannon's Blog 🐟 技術 | 生活 | 旅行! 如果你覺得我的文章有幫助,希望你可以到我的 github 給我一個 star ⭐️ Shannon Blog Repo
評論