Bootstrap

合并两个有序数组

hello 大家好!今天开写一个新章节,每一天一道算法题。让我们一起来学习算法思维吧!
在这里插入图片描述

/**
 * 合并两个按非递减顺序排列的整数数组 nums1 和 nums2 到 nums1 中
 * @param {number[]} nums1 - 第一个数组,长度为 m + n,后 n 个元素初始为 0
 * @param {number} m - nums1 中有效元素的数量
 * @param {number[]} nums2 - 第二个数组
 * @param {number} n - nums2 中元素的数量
 */
function merge(nums1, m, nums2, n) {
    // 初始化三个指针,分别指向 nums1 有效元素的末尾、nums2 的末尾以及合并后数组的末尾
    let p1 = m - 1; // 指向 nums1 中最后一个有效元素
    let p2 = n - 1; // 指向 nums2 中最后一个元素
    let p = m + n - 1; // 指向合并后数组 nums1 的最后一个位置

    // 从后往前比较 nums1 和 nums2 中的元素,并将较大的元素放到 nums1 的末尾
    while (p1 >= 0 && p2 >= 0) {
        if (nums1[p1] > nums2[p2]) {
            // 如果 nums1 当前元素大于 nums2 当前元素,将 nums1 的元素放到合并后数组的当前位置
            nums1[p] = nums1[p1];
            p1--; // 移动 nums1 的指针向前一位
        } else {
            // 否则,将 nums2 的元素放到合并后数组的当前位置
            nums1[p] = nums2[p2];
            p2--; // 移动 nums2 的指针向前一位
        }
        p--; // 移动合并后数组的指针向前一位
    }

    // 如果 nums2 中还有剩余元素,将它们依次复制到 nums1 的前面
    while (p2 >= 0) {
        nums1[p] = nums2[p2];
        p2--;
        p--;
    }

    // 这里不需要返回值,因为最终结果直接存储在 nums1 中
}

代码解释:

  1. 指针初始化:

p1 指向 nums1 中有效元素的最后一个位置(索引为 m - 1)。
p2 指向 nums2 中最后一个元素的位置(索引为 n - 1)。
p 指向合并后数组 nums1 的最后一个位置(索引为 m + n - 1)。

  1. 从后往前比较元素:

使用 while 循环,只要 p1 和 p2 都在有效范围内(即 p1 >= 0 且 p2 >= 0),就比较 nums1[p1] 和 nums2[p2] 的大小。
如果 nums1[p1] > nums2[p2],将 nums1[p1] 放到 nums1[p] 的位置,然后 p1 减 1,p 减 1。
否则,将 nums2[p2] 放到 nums1[p] 的位置,然后 p2 减 1,p 减 1。

  1. 处理 nums2 中剩余元素:

当 p1 小于 0 时,说明 nums1 中的有效元素已经全部处理完,但 nums2 中可能还有剩余元素。
使用另一个 while 循环,将 nums2 中剩余的元素依次复制到 nums1 的前面。

使用示例

let nums1 = [1, 2, 3, 0, 0, 0];
let m = 3;
let nums2 = [2, 5, 6];
let n = 3;

merge(nums1, m, nums2, n);
console.log(nums1); // 输出: [1, 2, 2, 3, 5, 6]
;