很有趣也比较简单的一道题。
问题描述
给你两个有序整数数组 nums1
和 nums2
,请你将 nums2
合并到 nums1
中,使 nums1
成为一个有序数组。
初始化 nums1
和 nums2
的元素数量分别为 m
和 n
。你可以假设 nums1
的空间大小等于 m + n
,这样它就有足够的空间保存来自 nums2
的元素。
解题思路
方法一 : 合并后排序
这是比较容易想到的解题思路,先把两个数组合并,再排序:
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
const merge = function(nums1, m, nums2, n) { for (let i = 0; i < n; i++) { nums1[nums1.length - 1 - i] = nums2[i]; }
return [nums1.sort((a, b) => a - b)[0]]; };
|
方法二 : 双指针 / 从前往后
初始化一个新的数组sorted
,用双指针选择最小的值插入到sorted
中,最后还要把sorted
重新遍历回nums1
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
const merge = function(nums1, m, nums2, n) { let p1 = 0; let p2 = 0; const sorted = new Array(m + n).fill(0); let cur; while (p1 < m || p2 < n) { if (p1 === m) { cur = nums2[p2++]; } else if (p2 === n) { cur = nums1[p1++]; } else if (nums1[p1] < nums2[p2]) { cur = nums1[p1++]; } else { cur = nums2[p2++]; } sorted[p1 + p2 - 1] = cur; } for (let i = 0; i != m + n; ++i) { nums1[i] = sorted[i]; } };
|
方法三 : 双指针 / 从后往前
前面两个方法都没有利用到题目中给的一个条件,两个有序数组,另外为了兼容其他语言,数组nums1
的长度都足够长了。这次还是用双指针,不过是从数组尾部遍历,找最大的,直接填入到nums1
中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
const merge = function(nums1, m, nums2, n) { let p1 = m - 1; let p2 = n - 1; let tail = m + n - 1; let cur; while (p1 >= 0 || p2 >= 0) { if (p1 === -1) { cur = nums2[p2--]; } else if (p2 === -1) { cur = nums1[p1--]; } else if (nums1[p1] > nums2[p2]) { cur = nums1[p1--]; } else { cur = nums2[p2--]; } nums1[tail--] = cur; } };
|
更 hack 的写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
const merge = function(nums1, m, nums2, n) { let len = m + n; while (n > 0) { if (m <= 0) { nums1[--len] = nums2[--n]; continue; } nums1[--len] = nums1[m - 1] >= nums2[n - 1] ? nums1[--m] : nums2[--n]; } };
|