【leetcode】合并两个有序数组

本文详细解释了一个JavaScript函数,用于在原地合并两个已排序数组nums1和nums2,通过m和n参数控制,不返回新数组,而是直接修改nums1。

在这里插入图片描述

/**
 * @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) {
    var len=m+n-1;
    m=m-1;
    n=n-1;
    while(m>=0&&n>=0){
        nums1[len]=nums1[m]>nums2[n]?nums1[m--]:nums2[n--];
        len--;
    }
    return nums1.splice(0,n+1,...nums2.slice(0,n+1));
};
<think>好的,我需要解决用户在LeetCode合并两个有序数组的问题,并提供C++的解决方案,包括测试用的main函数。首先,我需要回顾一下合并两个有序数组的常见方法。 根据用户提供的引用,特别是引用[4]和[5],合并两个有序数组的一种高效方法是从后往前填充数组,这样可以避免从前往后合并时可能出现的元素覆盖问题。因为题目中提到数组A有足够的空间容纳B的元素,所以不需要额外申请空间,这样可以达到O(m+n)的时间复杂度和O(1)的空间复杂度。 接下来,我需要将这个方法转化为C++代码。根据引用[4]中的Java示例,我们可以调整指针的起始位置。例如,使用三个指针:ia指向A的最后一个有效元素,ib指向B的最后一个元素,icur指向合并后的数组末尾。然后比较A[ia]和B[ib],将较大的元素放入icur位置,并向前移动相应的指针。如果B中还有剩余元素,继续填充到A的前面。 同时,要注意C++中数组的索引是从0开始的,所以初始化ia为m-1,ib为n-1,icur为m+n-1。循环条件应该是ia >=0 && ib >=0,处理完较大的元素后,处理剩余的B元素。 然后,关于测试的main函数部分,需要创建A数组时预留足够的空间,比如使用vector<int> A(m + n)或者动态数组。初始化A的前m个元素为有序,B的n个元素也为有序。调用merge函数后,输出合并后的数组。 需要检查代码是否符合LeetCode的要求,例如函数签名为void merge(vector<int>& nums1, int m, vector<int>& nums2, int n)。同时,测试用例要覆盖A和B的各种情况,比如A为空,B为空,或者元素交错的情况。 最后,确保代码中没有语法错误,比如正确的循环结构,指针移动,以及向量的正确使用。测试main函数应该能够正确运行并输出结果。</think>### C++实现合并两个有序数组LeetCode解决方案 #### 解决方案说明 题目要求将两个已排序数组合并到第一个数组中,且第一个数组有足够的空间容纳所有元素。最优解法采用**逆向双指针法**,时间复杂度$O(m+n)$,空间复杂度$O(1)$。关键点是从两个数组的末尾开始比较,避免正向合并时的元素覆盖问题[^4][^5]。 #### 完整代码实现 ```cpp #include <vector> #include <iostream> using namespace std; class Solution { public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int i = m - 1; // nums1有效元素末尾 int j = n - 1; // nums2末尾 int k = m + n - 1; // 合并后数组末尾 // 逆向比较填充 while (i >= 0 && j >= 0) { nums1[k--] = (nums1[i] > nums2[j]) ? nums1[i--] : nums2[j--]; } // 处理nums2剩余元素 while (j >= 0) { nums1[k--] = nums2[j--]; } } }; // 测试用例 int main() { vector<int> A = {1,3,5,0,0,0}; // 初始化预留空间 vector<int> B = {2,4,6}; Solution().merge(A, 3, B, 3); cout << "合并后数组: "; for (int num : A) { cout << num << " "; } return 0; } ``` **输出结果**: `合并后数组: 1 2 3 4 5 6` #### 代码解析 1. **逆向指针初始化**:`i`指向nums1最后一个有效元素,`j`指向nums2末尾,`k`指向合并后的末尾位置。 2. **核心循环**:比较两数组当前最大值,选择较大的放入`nums1[k]`,并移动对应指针。 3. **剩余元素处理**:若nums2仍有元素未合并,直接填充到nums1前端。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值