leetcode刷題 88 合併兩個有序陣列

2021-10-07 03:37:05 字數 2770 閱讀 1477

給你兩個有序整數陣列 

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 中的元素。示例 輸...