【每日一题】LeetCode - 合并两个有序数组

在这篇博客中,我们将讨论一个常见的编程问题:如何合并两个按非递减顺序排列的整数数组,使得合并后的数组仍然按非递减顺序排列。我们将通过一个具体的例子和 C++ 的实现来帮助大家理解这个过程。

问题描述

给定两个整数数组 nums1nums2,以及两个整数 mn,其中 m 表示 nums1 中的有效元素数量,而 n 表示 nums2 中的元素数量。我们的目标是将 nums2 合并到 nums1 中,使得合并后的数组仍然保持非递减顺序。

输入输出示例

示例 1:

  • 输入:nums1 = [1, 2, 3, 0, 0, 0], m = 3, nums2 = [2, 5, 6], n = 3
  • 输出:[1, 2, 2, 3, 5, 6]

示例 2:

  • 输入:nums1 = [1], m = 1, nums2 = [], n = 0
  • 输出:[1]

解决思路

  • 我们可以将两个数组合并成一个,然后对其进行排序,stlsort方法直接排完序之后返回,也可以使用快速排序对其进行排序返回(快速排序的平均时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),递归深度为 log ⁡ n \log n logn,每次操作需要的线性时间为 O ( n ) O(n) O(n))
  • 双指针法来解决这个问题。由于 nums1 的末尾包含足够的空间来容纳 nums2 中的所有元素,因此我们可以从后向前填充 nums1,这么做的时间复杂度是 O ( m + n ) O(m+n) O(m+n),空间复杂度是 O ( 1 ) O(1) O(1),因为我们最多循环m + n 次,由于没有占用额外的空间,所以时间复杂度是常数

具体步骤

排序

排序的方式很简单,先对两个数组合并然后直接sort就行了,我这里没有用这个办法,太简单了不想写。

双指针

  1. 定义两个指针 mn,分别指向 nums1nums2 的有效元素的最后一个索引。
  2. 定义一个指针 tail,指向合并后数组的最后一个位置。
  3. 比较 nums1[m-1]nums2[n-1],将较大的元素放到 nums1[tail] 中,并移动相应的指针。
  4. 如果 nums2 中的元素未完全处理完,则继续将剩余的元素填入 nums1
  5. 最终,nums1 将包含合并后的有序数组。
c++ 复制代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int tail = m + n - 1; // 合并后数组的最后一个位置
        while (n > 0 && m > 0) {
            // 从后向前比较并填充
            nums1[tail--] = nums1[m - 1] > nums2[n - 1] ? nums1[--m] : nums2[--n];
        }
        // 如果上面的循环循环完了,m中的元素可能已经全部取出,但n的元素不一定全部取出
        while (n > 0) {
            nums1[tail--] = nums2[--n];
        }
    }
};
代码解析
  • tail 初始化为 m + n - 1,指向合并后数组的最后一个位置。
  • while 循环中,我们比较 nums1nums2 中的元素,并将较大的元素放到 nums1[tail]。这确保了合并后的数组保持非递减顺序。
  • nums2 中还有元素未处理完时,我们需要将它们填入 nums1

时间复杂度和空间复杂度

  • 时间复杂度:O(m + n),因为我们需要遍历两个数组的所有元素。
  • 空间复杂度:O(1),由于我们在原地进行合并,不需要额外的空间。

结论

通过上述方法,我们成功地将两个有序数组合并为一个新的有序数组。希望这篇博客能帮助你理解合并有序数组的过程和相关的 C++ 实现

相关推荐
XiaoLeisj27 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿2 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd2 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v2 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A3 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组