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]
}
}