LeetCode 88 合併兩個有序數組
題目
給定兩個有序整數數組 nums1 和 nums2,將 nums2 合併到 nums1 中,使得 num1 成爲一個有序數組。
說明:
初始化 nums1 和 nums2 的元素數量分別爲 m 和 n。
你可以假設 nums1 有足夠的空間(空間大小大於或等於 m + n)來保存 nums2 中的元素。
示例:
輸入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
輸出: [1,2,2,3,5,6]
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/merge-sorted-array
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
解析及代碼
way 1
# 有一個想法是:直接把nums2放到nums1後面,然後直接對這m+n個元素進行快排
# from typing import List
# class Solution:
# def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
# """
# Do not return anything, modify nums1 in-place instead.
# """
# for i in range(len(nums2)):
# nums1.insert(m+i,nums2[i])
# # print(nums1)
# # 然後就可以給前m+n個元素進行快速排序了。
# nums1[:] = sorted(nums1[:m+n]) # 。。。python可以直接對其進行排序,但是時間複雜度並不是很高,因爲並沒有利用已經部分有序的特點
# # print(nums1)
way 2
# 一般而言,對於有序數組可以通過 雙指針法 達到O(n + m)O(n+m)的時間複雜度。
# 最直接的算法實現是將指針p1 置爲 nums1的開頭, p2爲 nums2的開頭,在每一步將最小值放入輸出數組中。
# 由於 nums1 是用於輸出的數組,需要將nums1中的前m個元素放在其他地方,也就需要 O(m)O(m) 的空間複雜度。
# from typing import List
# class Solution:
# def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
# """
# Do not return anything, modify nums1 in-place instead.
# """
# # first copy list nums1
# temp = nums1[:m]
# nums1 = []
# # 然後可以對temp 和 nums2進行一個一個的比較,然後依次放入nums1中
# left1 = 0
# left2 = 0
# while left1 < m and left2 < n:
# if temp[left1] < nums2[left2]:
# nums1.append(temp[left1])
# left1 += 1
# else:
# nums1.append(nums2[left2])
# left2 += 1
# # 其中一個列表已經比較完了,那就把另一個剩下的直接全部插入nums1中
# if left1 < m:
# nums1[left1+left2:] = temp[left1:]
# if left2 < n:
# nums1[left1+left2:] = nums2[left2:]
# print(nums1)
way 3
# way 3
# 第二個方法已經實現很好的時間複雜度,但是之前比較困擾的就是要先把nums1複製走,在從頭開始比較,需要花費額外的空間複雜度,
# 題解中第三種方法還是 雙指針法,但是是從後往前開始比較,並用一個 指針p來記錄nums1從後往前插入的位置
from typing import List
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
right1 = m - 1
right2 = n - 1
p = m+n-1 # 也就是最大的元素應該插入的位置
while right1 >= 0 and right2 >= 0:
if nums1[right1] > nums2[right2]:
nums1[p] = nums1[right1]
right1 -= 1
else:
nums1[p] = nums2[right2]
right2 -= 1
p -= 1
# if right1 >= 0 : 這種情況不需要處理啊,直接就是對的
nums1[:right2+1] = nums2[:right2+1]
print(nums1)
nums1 = [1,2,3,0,0,0]
m = 3
nums2 = [2,5,6]
n = 3
solu = Solution()
solu.merge(nums1,3,nums2,3)
思考
如果直接遇到這種有序數組問題,就可以考慮雙指針的方法