↓快轉到主要內容
  1. LeetCode/

LeetCode 88: Merge Sorted Array

·2 分鐘· ·
LeetCode Easy Two-Pointers Merge-Sort
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: easy 第一次嘗試:2026-10-18 來源:Merge sort 練習梯子,第 0 階

解題思路
#

nums1 的長度是 m + n,後面 n 格是空位。兩個陣列都已排序,所以只需要 merge sort 裡的 merge 這一步。

如果從前面填,會蓋掉 nums1 還沒讀的元素。從後面填就不會:寫入位置 k 永遠不會超過還沒讀的位置 i。

我的第一版
#

i = m - 1
j = n - 1
k = m + n - 1

while i >= 0 or j >= 0:
    if j == -1 or (nums1[i] > nums2[j] and i >= 0):
        nums1[k] = nums1[i]
        i -= 1
    else:
        nums1[k] = nums2[j]
        j -= 1
    k -= 1

結果正確,但有兩個可以改的地方:

  • 判斷順序:i == -1 時會先讀 nums1[-1] 才檢查 i >= 0。Python 的負索引剛好讓它不出錯,但在 Java/C++ 會越界。邊界檢查要放前面,利用 short-circuit 保護後面的存取。
  • 迴圈跑太久:nums2 用完以後,nums1 剩下的元素已經在正確位置,這時 k == i,等於把元素複製到自己身上。迴圈條件改成 while j >= 0 就夠了。

正確解法
#

class Solution:
    def merge(self, nums1: list[int], m: int, nums2: list[int], n: int) -> None:
        i, j, k = m - 1, n - 1, m + n - 1
        while j >= 0:
            if i >= 0 and nums1[i] > nums2[j]:
                nums1[k] = nums1[i]
                i -= 1
            else:
                nums1[k] = nums2[j]
                j -= 1
            k -= 1

另一種寫法:從前往後 + 暫存陣列
#

這就是 merge sort 標準的 merge,LC 912 會直接用到:

a = nums1[:m]
i = j = 0
for k in range(m + n):
    if j >= n or (i < m and a[i] <= nums2[j]):
        nums1[k] = a[i]
        i += 1
    else:
        nums1[k] = nums2[j]
        j += 1

複雜度
#

寫法時間額外空間
從後往前O(m + n)O(1)
從前往後 + 暫存O(m + n)O(m)
合併後整個重排O((m + n) log(m + n))不建議

要特別避免的錯誤
#

  • 先讀陣列才檢查邊界。
  • 從前面填卻沒有暫存,蓋掉還沒讀的元素。

面試口說整理
#

兩個陣列都已排序,所以只需要 merge 這一步。nums1 的空位在尾巴,我從後往前填,每次放兩邊目前最大的值,這樣不會蓋掉還沒讀的元素,可以做到 O(m + n) 時間、O(1) 額外空間。nums2 用完就可以停,因為 nums1 剩下的部分已經在正確位置。

相關文章

LeetCode 21: Merge Two Sorted Lists
·2 分鐘
LeetCode Easy Linked-List Two-Pointers Merge-Sort
LeetCode 21 解題筆記:dummy node,以及 Python 變數為什麼不是 copy
LeetCode 1826: Faulty Sensor
·1 分鐘
LeetCode Easy Two-Pointers Array
LeetCode 1826 解題筆記:找到第一個不同的位置後,比對兩種「誰掉了資料」的情況;兩種都成立時無法判斷,回傳 -1
LeetCode 2200: Find All K-Distant Indices in an Array
·1 分鐘
LeetCode Easy Two-Pointers Array
LeetCode 2200 解題筆記:每個 key 往左右各延伸 k 格,用一個指針記住已經輸出到哪裡,避免重疊的區間重複輸出
LeetCode 3794: Reverse String Prefix
·1 分鐘
LeetCode Easy Two-Pointers String
LeetCode 3794 解題筆記:切片一行解決;手寫雙指針時要先把字串轉成 list
LeetCode 3884: First Matching Character From Both Ends
·1 分鐘
LeetCode Easy Two-Pointers String
LeetCode 3884 解題筆記:從兩端往中間比,第一個相等的位置就是答案;長度是奇數時中間一定相等
LeetCode 2540: Minimum Common Value
·1 分鐘
LeetCode Easy Two-Pointers Array
LeetCode 2540 解題筆記:兩個排序好的陣列各一個指針,比較小的那邊往前,第一次相等就是答案