88. 合并两个有序数组

422 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

88. 合并两个有序数组

力扣题目链接

给你两个按 非递减顺序 排列的整数数组 nums1nums2,另有两个整数 mn ,分别表示 nums1nums2 中的元素数目。

请你 合并 nums2nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

思路:

需要注意的是,题目要求不要返回任何数据,要在原地修改nums1来达到最终目的。

按照题目要求,可以从数组1的末尾开始添加元素,找到数组1最后一位元素和数组2的最后一位元素,哪个元素更大,就将哪个元素放到数组1的末尾。这样合并后的数组就是非递减顺序。

通过指针len、len1、len2的递减,达到了指针左移的效果。如果数组1是空数组,则直接将数组2的元素依次放入数组1即可。

合并

/**
 * @param {number[]} nums1
 * @param {number} m
 * @param {number[]} nums2
 * @param {number} n
 * @return {void} Do not return anything, modify nums1 in-place instead.
 */
var merge = function(nums1, m, nums2, n) {
    let len1 = m - 1;
    let len2 = n - 1;
    let len = m + n - 1;
    while(len2 >= 0) {
        if (len1 < 0) {
            nums1[len--] = nums2[len2--];
        }
        nums1[len--] = nums1[len1] >= nums2[len2] ? nums1[len1--] : nums2[len2--];
    }
};

总结

本题考查有序数组的合并,跟有序链表是非类似,但是链表必须从头开始遍历,数组则不需要。核心思路是从后往前追加元素,较大者放入数组的末尾。难度系数简单。

相比之下,合并两个有序链表一般是创建一个哨兵节点,然后对比并找到两个链表中较小元素,依次追加到哨兵节点后,最后返回哨兵节点next指针便是一个合并后的有序链表。