Loading

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]
	}
}
posted @ 2021-07-17 15:33  励码万言  阅读(31)  评论(0编辑  收藏  举报