給定兩個已排序的整數陣列 nums1 和 nums2,請將 nums2 合併到 nums1 中,使合併後的陣列仍保持有序。
關鍵條件:
nums1 擁有足夠的空間容納 nums2 的所有元素(即 nums1.length == m + n)nums1 的有效長度為 m,nums2 的有效長度為 nnums1 上原地修改,不返回任何值範例:
輸入: nums1 = [1, 1, 2, 2, 4, 0, 0, 0, 0], m = 5
nums2 = [0, 0, 2, 3], n = 4
輸出: nums1 變為 [0, 0, 1, 1, 2, 2, 2, 3, 4]
既然兩個陣列都是有序的,且 nums1 尾部有足夠空間,我們可以從後向前遍歷,避免覆蓋 nums1 中尚未處理的元素。
index = m + n - 1(合併後陣列的最後位置)、i = m - 1(nums1 有效元素末尾)、j = n - 1(nums2 末尾)i >= 0 且 j >= 0 時,比較 nums1[i] 和 nums2[j],將較大者放入 nums1[index],並移動相應指針nums2 還有剩餘元素(j >= 0),直接複製到 nums1 前段;若 nums1 有剩餘則無需操作,因為它們已在正確位置時間複雜度:O(m + n),空間複雜度:O(1)。
class Solution:
def merge(self, nums1, m, nums2, n):
"""
:type nums1: List[int]
:type m: int
:type nums2: List[int]
:type n: int
:rtype: void Do not return anything, modify nums1 in-place instead.
"""
index = m + n - 1
i, j = m - 1, n - 1
while i >= 0 and j >= 0:
if nums1[i] > nums2[j]:
nums1[index] = nums1[i]
i -= 1
else:
nums1[index] = nums2[j]
j -= 1
index -= 1
# 若 nums2 有剩餘,直接複製
if j >= 0:
nums1[:j + 1] = nums2[:j + 1]
# 測試
if __name__ == "__main__":
nums1 = [1, 1, 2, 2, 4, 0, 0, 0, 0]
nums2 = [0, 0, 2, 3]
Solution().merge(nums1, 5, nums2, 4)
assert nums1 == [0, 0, 1, 1, 2, 2, 2, 3, 4]
print("測試通過:", nums1)
nums1 尾部空間,從大到小填充,避免數據覆蓋nums2 的剩餘元素,nums1 的剩餘元素天然就位這道題是雙指針技巧的經典應用,掌握「從後向前」的合併策略,能輕鬆解決類似的有序陣列合併問題。