給你兩個有序整數陣列
nums1 和
nums2,請你將
nums2 合併到
nums1 中
,使 nums1 成為乙個有序陣列。
這種解法運用到了歸併排序的思想:使用雙指標同時遍歷兩個陣列,比較指標指向元素的大小,將小的元素放到正確的位置即可。
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.
"""i = 0
j = 0
index = 0
tmp = nums1.copy()
while(i < m and j < n):
if(tmp[i] <= nums2[j]):
nums1[index] = tmp[i]
i += 1
index += 1
else:
nums1[index] = nums2[j]
j += 1
index += 1
while(i時間複雜度為o(m+n),空間複雜度為o(m)
在上述**中 ,有一行**需要注意,即tmp = nums1.copy(), 看如下**:
nums = [1,2,3,0,0,0]
print(id(nums)) # 2927496620680
# 方式一
tmp = nums
print(tmp) # [1, 2, 3, 0, 0, 0]
print(id(tmp)) # 2927496620680
# 方式二
tmp1 = nums.copy()
print(tmp1) # [1, 2, 3, 0, 0, 0]
print(id(tmp1)) # 2927496550920
# 方式三
tmp2 = nums[:]
print(tmp2) # [1, 2, 3, 0, 0, 0]
print(id(tmp2)) # 2927496551048
可以發現,三種方式下,陣列tmp、tmp1、tmp2中的值都是一樣的,但是在方式一的情況下,tmp和nums的id是一樣的,也就是兩個變數指向記憶體當中同一塊位址;而在方式二和三的情況下,tmp2和t***只是和nums中的值一致,id是不一樣的,即這三個變數分別指向不同的記憶體位址。那麼指向同一記憶體位址會有什麼影響呢?此時,如果我們改變tmp中元素的值,如tmp[1] = 20,則會發現nums[1]的值變為20。而若我們改變tmp1和tmp2的值,則不會影響nums中的值,因為這三個變數指向不同的記憶體單元。
對比方式一和方式三,我們發現python中nums 與nums[:] 的不同,nums[:]等價於nums[0, len(nums)],只是將陣列中的值賦給等號右邊的變數;而tmp = nums的方式,我們可以理解為每乙個記憶體位址都會有變數名字與之對應,這個對應關係是一對多的,即2927496620680這個位址開始有個變數名為nums,而tmp = nums則是給這個位址又起了乙個新的名字tmp。
原題中要求我們直接在num1上改動,因此我們申請的臨時變數tmp只能用方式二或者方式三的方式賦值,若用方式一,會產生錯誤答案。
只需要將nums1的前m個元素和nums2的n個元素組成乙個新的陣列,然後直接排序。
def merge(self, nums1, m, nums2, n):
""":type nums1: list[int]
:type m: int
:type nums2: list[int]
:type n: int
:rtype: none do not return anything, modify nums1 in-place instead.
"""nums1[:] = sorted(nums1[:m] + nums2)
演算法的時間複雜度為o((n+m)(log(n+m))),空間複雜度為o(1)
解法一中已經達到了最好的時間複雜度,我們考慮有沒有辦法進一步降低空間複雜度?之所以需要o(m)的空間複雜度,是因為我們從前往後遍歷兩個陣列,每次取出較小的值放於nums1中,因此我們需要提前將nums1中的元素儲存下來。那麼,如果是從後往前遍歷,每次取出較大的值呢?**如下
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.
"""i = m-1
j = n-1
index = m+n-1
while(i >=0 and j >=0):
if(nums1[i] <= nums2[j]):
nums1[index] = nums2[j]
j -= 1
index -= 1
else:
nums1[index] = nums1[i]
i -= 1
index -= 1
nums1[: j+1] = nums2[:j+1]
此時,演算法的時間複雜度為o(m+n),空間複雜度為o(1)。
LeetCode刷題之路 88 合併兩個有序陣列
給你兩個有序整數陣列 nums1 和 nums2,請你將 nums2 合併到 nums1 中,使 nums1 成為乙個有序陣列。說明 初始化 nums1 和 nums2 的元素數量分別為 m 和 n 你可以假設 nums1 有足夠的空間 空間大小大於或等於 m n 來儲存 nums2 中的元素。示例...
LeetCode刷題 88 合併兩個有序陣列
給定兩個有序整數陣列 nums1 和 nums2,將 nums2 合併到 nums1 中,使得 num1 成為乙個有序陣列。說明 初始化 nums1 和 nums2 的元素數量分別為 m 和 n。你可以假設 nums1 有足夠的空間 空間大小大於或等於 m n 來儲存 nums2 中的元素。雙指標法...
LeetCode 題 88 合併兩個有序陣列
給定兩個有序整數陣列 nums1 和 nums2,將 nums2 合併到 nums1 中,使得 num1 成為乙個有序陣列。說明 初始化 nums1 和 nums2 的元素數量分別為 m 和 n。你可以假設 nums1 有足夠的空間 空間大小大於或等於 m n 來儲存 nums2 中的元素。示例 輸...