iT邦幫忙

2025 iThome 鐵人賽

DAY 4
0

Middle of the Linked List (Linked List) 876

question

  • 給定一個單向鏈結串列,找到其中間節點並回傳。
  • 如果有兩個中點(鏈結串列長度為偶數),則回傳第二個中點。
    Ex.
    1 -> 2 -> 3 -> 4 -> 5 → 回傳節點 3
    1 -> 2 -> 3 -> 4 -> 5 -> 6 → 回傳節點 4

thoughts

方法 1:快慢指針 (Two Pointers)(最常見)

  • 設定 slow 和 fast 指針,都從頭節點出發。
  • fast 每次走 2 步,slow 每次走 1 步。
  • 當 fast 到達尾端 時,slow 剛好在中點。
  • 如果長度是奇數:slow 停在正中間。
  • 如果長度是偶數:slow 停在第二個中點(符合題目要求)。
  • 時間複雜度:O(n)
  • 空間複雜度:O(1)
    方法 2:遍歷 + 陣列存儲
  • 遍歷整個鏈表,把所有節點存到陣列中。
  • 用 size / 2 找出中間節點並回傳。
  • 時間複雜度:O(n)
  • 空間複雜度:O(n)
  • cons: 需要額外空間,不如快慢指針高效
    方法 3:兩次遍歷
  • 第一次遍歷,計算鏈表長度 n。
  • 第二次遍歷,走 n/2 步,停下來就是中點。
  • 時間複雜度:O(n)
  • 空間複雜度:O(1)
  • 比快慢指針多一次遍歷,不是最佳解

summary

為什麼快慢指針最好?
只需要一次遍歷,效率最高。
不用額外空間,比陣列法更省記憶體。
能自動解決偶數長度鏈表回傳「第二個中點」的需求。

Kotlin


class Solution {
    fun middleNode(head: ListNode?): ListNode? {
        var slow = head
        var fast = head
        while (fast?.next != null) {
            slow = slow?.next
            fast = fast.next?.next
        }
        return slow
    }
}

Follow-up

  • 如果鏈結串列長度為偶數,應該回傳前一個中點還是後一個中點?(LeetCode 預設回傳後一個)
  • 是否能在 一次遍歷 中解決?(快慢指針就是一次遍歷)
  • 如何擴展成找到 1/3 點或 1/4 點?

上一篇
#17
下一篇
#19
系列文
來都來了-涮就涮吧20
  1. 16
    #15
  2. 17
    #16
  3. 18
    #17
  4. 19
    #18
  5. 20
    #19
完整目錄
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言