1. 程式人生 > 其它 >LeetCode88.合併兩個有序陣列

LeetCode88.合併兩個有序陣列

題目

給你兩個有序整數陣列nums1 和 nums2,請你將 nums2 合併到nums1中,使 nums1 成為一個有序陣列。

初始化nums1 和 nums2 的元素數量分別為m 和 n 。你可以假設nums1 的空間大小等於m + n,這樣它就有足夠的空間儲存來自 nums2 的元素。

示例 1:

輸入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3

輸出:[1,2,2,3,5,6]

示例 2:

輸入:nums1 = [1], m = 1, nums2 = [], n = 0

輸出:[1]

提示:

nums1.length == m + n

nums2.length == n

0 <= m, n <= 200

1 <= m + n <= 200

-109 <= nums1[i], nums2[i] <= 109

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/merge-sorted-array
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解題思路

直接合並排序

直接將nums2合併到nums1,然後呼叫函式進行快排
時間複雜度O((m+n)log(m+n))
空間複雜度O(log(m+n))

雙指標 + 輔助陣列

定義兩個指標分別指向兩陣列頭部,每次取出最小的結果放入輔助陣列中
時間複雜度O(m+n)
時間複雜度O(m+n)

逆向雙指標(推薦)

從兩陣列末尾開始比較,每次比較將最大元素放入nums1最後
時間複雜度O(m+n)
空間複雜度O(1) 直接對nums1進行修改,不需要額外的空間

程式碼解析

// 方法一:直接合並排序
func merge(nums1 []int,m int,nums2 []int,n int)  {
	copy(nums1[m:],nums2)
	sort.Ints(nums1)
}

// 方法二:雙指標 + 輔助陣列
func merge2(nums1 []int,m int,nums2 []int,n int)  {
	// 定義兩指標分別指向頭部
	p1,p2 := 0,0
	// 定義輔助陣列
	sorted := make([]int,0,m+n)
	// 當某個陣列已經指向最後一個元素時結束迴圈
	for {
		// 當陣列1已經指向最後一個元素,將陣列2剩餘元素新增進輔助陣列
		if p1 == m {
			sorted = append(sorted,nums2[p2:]...)
			break
		}
		// 當陣列2已經指向最後一個元素,將陣列1剩餘元素新增進輔助陣列
		if p2 == n {
			sorted = append(sorted,nums1[p1:]...)
			break
		}
		// 將小的元素新增到複製陣列,相應指標索引+1
		if nums1[p1] < nums2[p2]{
			sorted = append(sorted,nums1[p1])
			p1++
		}else{
			sorted = append(sorted,nums2[p2])
			p2++
		}
	}
	copy(nums1,sorted)
}


// 方法三:逆向雙指標
func merge3(nums1 []int,m int,nums2 []int,n int)  {
	// p 是nums1陣列長度 用於逆序存放元素
	for p := m + n;m > 0 && n > 0;p--{
		// 如果nums2末尾元素大於nums1末尾元素,將nums2末尾元素設定到nums1最後,nums2指標--
		if nums1[m-1] <= nums2[n-1]{
			nums1[p-1] = nums2[n-1]
			n--
		}else{
			nums1[p-1] = nums1[m-1]
			m--
		}
	}
	// 如果nums2還有剩餘元素,全部逆序放入nums1
	for ;n > 0;n--{
		nums1[n-1] =  nums2[n-1]
	}
}