【Leetcode】python - [206] Reverse Linked List 個人解法筆記 (內含範例程式碼) 內含 Linked List reverse 反轉操作 part 3 (for 新手教學)

題目出處

206. Reverse Linked List

難度

easy

題目分類

Linked List, Recursion

Linked List reverse 反轉操作 part 3

  • part1 基本概念 請參考: [【Leetcode】python – [21] Merge Two Sorted Lists 個人解法筆記 (內含範例程式碼) 內含 Linked List 基本操作 (for 新手教學)](https://wongwongnotes-github-io.pages.dev/python/leetcode-python-21/)
  • part2 remove 操作 請參考: [【Leetcode】python – [203] Remove Linked List Elements 個人解法筆記 (內含範例程式碼) 內含 Linked List remove 操作 part 2 (for 新手教學)](https://wongwongnotes-github-io.pages.dev/python/leetcode-python-203/)
  • 這邊我們要來研究 Linked list 的 反轉操作,
    一樣的,這操作硬要說也不難,但只要思緒不夠清楚,
    一定是轉了半天轉不出來XDD 最後絕望放棄XD

    我們試著來把概念講的簡單一點吧!

    試試看講簡單一點

    做反轉動作來說,最簡單我們都需要「三個紀錄點」,
    分別代表「過去」、「現在」、「未來」,
    每一個記錄點都非常重要,
    我們一定要注意「不能在過程中失去任何重要紀錄點,一旦被蓋掉就再也找不回來了!

    因此我們基本的策略就有了下圖,1 ~ 3,
    我們移動的方式一定是:

      - 過去 = 現在 - 現在 = 未來 - 未來 = 更未來

    到這邊,「務必務必謹守上述這個原則」,
    再來我們再來討論反轉,什麼時候適合做反轉呢?
    就是在做上述的「移動 1~3」之前,所以「更改」反轉的線,就是在第 0 步驟,

    初始化

    這裡有個小重點,不論如何,我們的 Linklist 最終「必須結束於 None」,
    因此我們要先宣告個「新結束點」給他
    那想當然,可以讓一開始 prev 擔任這個步驟。

    而我們真正作為起頭的 head ,可以先給予他 cur (代表現在),
    由於此時我們還不確定有沒有 head 存在,因此還不能直接給 head.next (會跳錯)

    個人範例程式碼

    記得上述所說的,我們需要先宣告 None 作為結尾

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
            prev = None # must have a None end.
            if head: # init 
                cur = head
                head = head.next
                cur.next = prev # must have a None end.
            else: # special case
                return head
    
            # loop
            while head:   
                prev = cur
                cur = head  
                head = head.next
                cur.next = prev # reverse
    
            return cur 
    

    Time Complexity

    O(n)

    Space Complexity

    O(1)

    算法說明

    遍歷一次 head 是一定要的,問題是我們該怎麼移除,
    移除的方法我們上面也提到過了,
    只需要把「下個」替換成「下下個」就可以輕鬆解決,
    只是要多考慮一些「不存在的邊際情況」,這邊我們下面會提。

    corner case 特殊情況處理

    一同整理在下方「邊際情況處理」

    Boundary conditions/ Edge conditions 邊際情況處理

    我們把題目稍微分析一下,我這裡大概把題目分類成於以下三種情況,

      - [None] - [1] - [1,2,3] <- 正常情況

    其中我們來看看 1.2. 我們該怎麼辦。

    1. [None]

    如果一開始 if head 就沒東西,我們就直接 return head

    2. [1]

    我們已經把 cur = head,而 while head 會直接判找不到東西,
    因此回傳 cur,沒有問題。

    Reference

    Licensed under CC BY-NC-SA 4.0