LeetCode 88 合併兩個有序數組

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)

思考

如果直接遇到這種有序數組問題,就可以考慮雙指針的方法

發佈了53 篇原創文章 · 獲贊 9 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章