题目描述
原题链接:合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。
要求对 nums1 原地操作,不用返回新数组。
示例
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解答
解法一
将两个数组拼接到一起再排序。
需要说明的是,输入的 nums1 的长度为 m + n,前 m 个成员是 nums1 实际成员,后面 n 个全是 0,因为在其他语言中一个 list 声明时就已指定长度,而 JavaScript 中的数组不是严格意义上的数组。
代码如下:
var merge = function (nums1, m, nums2, n) {
nums1.splice(m, nums1.length - m, ...nums2)
nums1.sort((a, b) => a - b)
}
复杂度分析
- 时间复杂度:O((M + N) * log(M + N)),拼接需要花费时间 O(M + N),排序按快排时间复杂度 O(log(M + N))。
- 空间复杂度:O(M + N),按快排复杂度为 O(log(M + N))
解法二
采用逆向双指针,每次比较两个数组最后的成员并在 nums1 数组最后填充进去:
var merge = function (nums1, m, nums2, n) {
let index1 = m - 1
let index2 = n - 1
while (index1 >= 0 || index2 >= 0) {
const tail = index1 + index2 + 1
if (index1 === -1) {
nums1[tail] = nums2[index2--]
} else if (index2 === -1) {
nums1[tail] = nums1[index1--]
} else if (nums1[index1] > nums2[index2]) {
nums1[tail] = nums1[index1--]
} else {
nums1[tail] = nums2[index2--]
}
}
}
复杂度分析:
- 时间复杂度:O(M + N),遍历两个数组总时间复杂度是 O(M + N)
- 空间复杂度:O(1),原地操作,不占空间