leedcode 合并两个有序数组

数组合并算法

因为nums1里面保证可以放下所有元素,所以从最大的元素开始比较,从nums1的最后面开始放元素。

class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        count = m + n - 1
        m = m - 1
        n = n - 1
        while m >= 0 and n >= 0:
            if nums1[m] >= nums2[n]:
                nums1[count] = nums1[m]
                count = count - 1
                m = m - 1
            else:
                nums1[count] = nums2[n]
                count = count - 1
                n = n -1
        while m >= 0:
            nums1[count] = nums1[m]
            count = count - 1
            m = m - 1
        while n >= 0:
            nums1[count] = nums2[n]
            count = count - 1
            n = n - 1
        return nums1

 

<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前端。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值