力扣每日一道系列 --- LeetCode 88. 合并两个有序数组

简介: 力扣每日一道系列 --- LeetCode 88. 合并两个有序数组


思路1:暴力求解

  1. 首先创建一个临时数组,其大小为第一个数组的大小(即nums1Size),其作用主要是。
  2. 通过循环遍历两个数组,将两个数组元素比较后较小的元素依次加入到临时数组中,直到有一个数组遍历完即可(注意:这里遍历完是只有效元素被遍历完,因为nums1中有无效元素0)。
  3. 将未遍历完的数组剩下的元素依次加入到临时数组中。
  4. 将临时数组中的元素依次拷贝到nums1数组中。
  5. 释放临时数组的空间。

    时间复杂度:O(m+n)
    空间复杂度:O(m+n)

值得注意的是: 这里需要考略到两种特殊情况需要单独处理

  • nums2 数组为空时,nums1 数组就是两个数组排序后的结果,函数不需要执行任何操作,直接 return 即可
  • nums1 数组中有效的元素个数为 0(即 m = 0 ) 时,此时 nums2 数组中的元素就是两个数组排序后的结果,此时只需要将 nums2 中的数组元素拷贝到 nums1 数组即可。
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    if(nums2==NULL)
    {
        return;
    }
    else if(m==0)
    {
        for(int i=0;i<nums1Size;i++)
        {
            nums1[i]=nums2[i];
        }
    }
    //创建一个数组来临时存放排序之后的元素,元素个数为m+n = nums1Size
    int *arr = (int*)malloc((nums1Size)*sizeof(int));
    int index = 0,dest = 0,src = 0;
    //dest和src分别标记访问当前数组元素的下标
    //index标记临时数组加入元素的下标位置
    //依次遍历两个数组,直到有一个数组遍历完为止
    while(dest < m && src < n)
    {
        if(nums1[dest]<=nums2[src])
        {
            arr[index++] = nums1[dest++];
        }
        else
        {
            arr[index++] = nums2[src++];
        }
    }
    //将未遍历完的数组剩下的元素加入到临时数组中
    if(src>=n)
    {
        while(dest<m)
        {
            arr[index++] = nums1[dest++];
        }
    }
    else if(dest>=m)
    {
        while(src<n)
        {
            arr[index++] = nums2[src++];
        }
    }
    //将临时数组中的元素依次赋值给nums1数组中对应位置的元素
    for(int i = 0;i<nums1Size;i++)
    {
        nums1[i] = arr[i];
    }
    free(arr);//将创建的数组空间释放
}

思路2:原地合并

  1. 从后往前遍历数组,将 nums1nums2 中的元素逐个比较,将较大的元素往 nums1 末尾进行搬移
  2. 第一步结束后,nums2 中可能会有数据没有搬移完,将 nums2 中剩余的元素逐个搬移到 nums1
  3. 如果 num1 中剩余元素没有搬移完,就不需要进行任何操作,因为 num1 中剩余的元素本来就在 num1

    时间复杂度:O(m+n)
    空间复杂度:O(1)
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    // end1、end2:分别标记nums1 和 nums2最后一个有效元素位置
    // end标记nums1的末尾,因为nums1和nums2中的元素从后往前往nums1中存放
    // ,否则会存在数据覆盖
    int end1 = m-1;
    int end2 = n-1;
    int index = m+n-1;
    // 从后往前遍历,将num1或者nums2中较大的元素往num1中end位置搬移
    // 直到将num1或者num2中有效元素全部搬移完
    while(end1 >= 0 && end2 >= 0)
    {
        if(nums1[end1] > nums2[end2])
        {
            nums1[index--] = nums1[end1--];
        }
        else
        {
            nums1[index--] = nums2[end2--];
        }
    }
    // num2中的元素可能没有搬移完,将剩余的元素继续往nums1中搬移
    while(end2 >= 0)
    {
        nums1[index--] = nums2[end2--];
    }
    // num1中剩余元素没有搬移完 ---不用管了,因为num1中剩余的元素本来就在num1中
}

如果大家有什么疑问可以在评论区与我讨论,或者直接私信我,感谢大家的阅读哦 ~

目录
相关文章
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
540 1
|
Go
【LeetCode 热题100】BFS/DFS 实战:岛屿数量 & 腐烂的橘子(力扣200 / 994 )(Go语言版)
本篇博客详细解析了三道经典的动态规划问题:198. 打家劫舍(线性状态转移)、279. 完全平方数与322. 零钱兑换(完全背包问题)。通过 Go 语言实现,帮助读者掌握动态规划的核心思想及其实战技巧。从状态定义到转移方程,逐步剖析每道题的解法,并总结其异同点,助力解决更复杂的 DP 问题。适合初学者深入理解动态规划的应用场景和优化方法。
412 0
|
分布式计算 算法 Go
【LeetCode 热题100】BFS/DFS 实战:岛屿数量 & 腐烂的橘子(力扣200 / 994 )(Go语言版)
本文讲解了两道经典的图论问题:**岛屿数量(LeetCode 200)** 和 **腐烂的橘子(LeetCode 994)**,分别通过 DFS/BFS 实现。在“岛屿数量”中,利用深度或广度优先搜索遍历二维网格,标记连通陆地并计数;“腐烂的橘子”则采用多源 BFS,模拟腐烂传播过程,计算最短时间。两者均需掌握访问标记技巧,是学习网格搜索算法的绝佳实践。
576 1
|
算法 Go 索引
【LeetCode 热题100】回溯:括号生成 & 组合总和(力扣22 / 39 )(Go语言版)
本文深入解析了LeetCode上的两道经典回溯算法题:**22. 括号生成**与**39. 组合总和**。括号生成通过维护左右括号数量,确保路径合法并构造有效组合;组合总和则允许元素重复选择,利用剪枝优化搜索空间以找到所有满足目标和的组合。两者均需明确路径、选择列表及结束条件,同时合理运用剪枝策略提升效率。文章附有Go语言实现代码,助你掌握回溯算法的核心思想。
601 0
|
Go 开发者 索引
【LeetCode 热题100】路径与祖先:二叉树中的深度追踪技巧(力扣33 / 81/ 153/154)(Go语言版)
本文深入探讨了LeetCode中四道关于「搜索旋转排序数组」的经典题目,涵盖了无重复和有重复元素的情况。通过二分查找的变形应用,文章详细解析了每道题的解题思路和Go语言实现代码。关键点包括判断有序区间、处理重复元素以及如何缩小搜索范围。文章还总结了各题的异同,并推荐了类似题目,帮助读者全面掌握二分查找在旋转数组中的应用。无论是初学者还是有经验的开发者,都能从中获得实用的解题技巧和代码实现方法。
571 14
|
Go
【LeetCode 热题100】路径与祖先:二叉树中的深度追踪技巧(力扣437 / 236 )(Go语言版)
本文深入探讨二叉树中路径与祖先问题,涵盖两道经典题目:LeetCode 437(路径总和 III)和236(最近公共祖先)。对于路径总和 III,文章分析了双递归暴力解法与前缀和优化方法,后者通过哈希表记录路径和,将时间复杂度从O(n²)降至O(n)。在最近公共祖先问题中,采用后序遍历递归查找,利用“自底向上”的思路确定最近公共祖先节点。文中详细解析代码实现与核心要点,帮助读者掌握深度追踪技巧,理解树结构中路径与节点关系的本质。这类问题在面试中高频出现,掌握其解法意义重大。
359 4
|
算法 Go
【LeetCode 热题100】深入理解二叉树结构变化与路径特性(力扣104 / 226 / 114 / 543)(Go语言版)
本博客深入探讨二叉树的深度计算、结构变换与路径分析,涵盖四道经典题目:104(最大深度)、226(翻转二叉树)、114(展开为链表)和543(二叉树直径)。通过递归与遍历策略(前序、后序等),解析每题的核心思路与实现方法。结合代码示例(Go语言),帮助读者掌握二叉树相关算法的精髓。下一讲将聚焦二叉树构造问题,欢迎持续关注!
444 10
|
新零售 人工智能 自动驾驶
长江商学院 x 阿里巴巴集团数智创新学院 | 第三模块「金融数智创新和组织升级」
编者按: 风好正是扬帆时,奋楫逐浪天地宽。春回大地,万物复苏之际,正是砥砺奋进昂首迈步之时。2022 年2月24日,数智创新学院再聚杭州,与长江商学院 x 阿里巴巴一道开启第三模块充电学习,引领创新变革,书写奋进新篇章。
2058 0
|
8月前
|
弹性计算 人工智能 数据可视化
阿里云轻量应用服务器指南:省钱购买、远程连接及使用全教程
阿里云轻量应用服务器,2核2G配置,200M峰值带宽仅38元/年,新用户专享。支持一键部署WordPress、宝塔面板等,适合个人建站、学习测试。操作简单,管理便捷,提供可视化远程连接。高阶需求可选云服务器ECS。
|
4月前
|
数据采集 人工智能 监控
快速接入小红书API,市场趋势与热点预测
小红书API+AI已成2026年品牌营销与内容电商核心基建,支持竞品监测、舆情预警、趋势预测等全场景合规数据采集;多模态生成、预测型AI与垂直领域模型加速商业化落地,SaaS工具、代运营、技术基建成三大机遇。(239字)
1177 2