当前位置: 首页 > news >正文

面试经典150题[001]:合并两个有序数组(LeetCode 88)

合并两个有序数组(LeetCode 88)

https://leetcode.cn/problems/merge-sorted-array/?envType=study-plan-v2&envId=top-interview-150

1. 题目背景

你有两个已经排好序的数组:

  • nums1:前面是有效数字,后面是空位(0 占位),用来放另一个数组的元素。
  • nums2:完整的、也是排好序的数组。

目标是把 nums2 的元素合并到 nums1 中,并且 最终 nums1 还是升序


例子

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

前 3 个数 [1, 2, 3] 是有效的,后面 3 个 0 是空位。
要把 [2, 5, 6] 填进去,最终得到:

[1, 2, 2, 3, 5, 6]

2. 常见但低效的解法

有些同学会这样做:

  1. nums2 直接加到 nums1 的后面。
  2. 调用 .sort() 排序。

虽然能跑通,但时间复杂度是 O((m+n) log(m+n)),不够快。
面试官通常会追问:能不能 O(m+n) 时间完成?


3. 高效解法——从尾巴开始合并

关键思路

因为两个数组都是升序的,我们可以用 双指针尾部 往前填空位。

这样有两个好处:

  • 不会覆盖掉还没处理的数字。
  • 不需要移动数组中已有的元素。

三个指针的定义

  • p1 = m - 1 → 指向 nums1 有效部分的最后一个元素
  • p2 = n - 1 → 指向 nums2 的最后一个元素
  • p = m + n - 1 → 指向 nums1 的最后一个位置(空位)

合并过程(例子推演)

nums1 = [1,2,3,0,0,0]nums2 = [2,5,6] 为例:

步骤p1指向p2指向比较放到 p 位置数组状态
1366 大放 6[1,2,3,0,0,6]
2355 大放 5[1,2,3,0,5,6]
3323 大放 3[1,2,3,3,5,6]
422一样大,放 nums2 的 2[1,2,2,3,5,6]
结束p2 < 0完成

4. 为什么要 p1 >= 0 判断?

如果 nums1 的有效部分先用完(p1 < 0),那就不能再访问 nums1[p1],否则会越界(尤其在 C++ 里直接崩溃)。
所以我们要保护一下:

if p1 >= 0 and nums1[p1] > nums2[p2]:...
else:...

5. Python 实现

def merge(nums1, m, nums2, n):p1 = m - 1p2 = n - 1p = m + n - 1while p2 >= 0:if p1 >= 0 and nums1[p1] > nums2[p2]:nums1[p] = nums1[p1]p1 -= 1else:nums1[p] = nums2[p2]p2 -= 1p -= 1

6. C++ 实现

#include <vector>
using namespace std;void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {int p1 = m - 1;int p2 = n - 1;int p = m + n - 1;while (p2 >= 0) {if (p1 >= 0 && nums1[p1] > nums2[p2]) {nums1[p] = nums1[p1];p1--;} else {nums1[p] = nums2[p2];p2--;}p--;}
}

7. 小结

口诀

三指针,从尾走,谁大放谁,谁没了放另一个。

  • 从尾往前填空位,不会破坏还没处理的数字。
  • p1 >= 0 防止越界。
  • 最终复杂度 O(m+n),空间 O(1)。
http://www.dtcms.com/a/327663.html

相关文章:

  • 【代码随想录day 17】 力扣 98.验证二叉搜索树
  • iis无法访问文件
  • NTP常见日志分析
  • 每日五个pyecharts可视化图表-line:从入门到精通 (4)
  • 多轮问答与指代消解
  • 测试匠谈 | AI语音合成之大模型性能优化实践
  • @JsonAnyGetter 动态表格渲染的“神”
  • 「机器学习」:金融风控贷款违约预测,天池比赛解决详细思路
  • Redis面试精讲 Day 19:Redis缓存设计模式与策略
  • 剑指offer第2版——面试题3:数组中重复的数字
  • RabbitMQ-知识技能图谱(总结篇)
  • 【时时三省】(C语言基础)建立动态链表
  • LeetCode189~191、198~214题解
  • 探秘酵母单杂交技术:解锁基因调控的密码
  • WEB虚拟主机3种部署方式全解析
  • 【Java Web 快速入门】九、事务管理
  • 【数据分享】2018-2024年中国10米分辨率春小麦和冬小麦分布栅格数据
  • Unity:GUI笔记(一)——文本、按钮、多选框和单选框、输入框和拖动条、图片绘制和框绘制
  • vue3大事件
  • 4.运算符
  • TF-IDF——红楼梦案例
  • IIS Express中可以同时加载并使用.net4.0和.NET 2.0的 DLL
  • Linux服务:Apache 虚拟主机配置指南:多站点部署三种方式详解
  • 【DL】浅层神经网络
  • 一键设置 NTP 时区的脚本(亲测,适用于部署 K8S 的前置环境)
  • 测试环境下因网络环境变化导致集群无法正常使用解决办法
  • Java调用Vue前端页面生成PDF文件
  • 【K8s】K8s控制器——Deamonset、Statefulset、Job与CronJob
  • 基于 Easy Rules 的电商订单智能决策系统:构建可扩展的业务规则引擎实践
  • 使用ceph-deploy安装和配置RADOS Gateway (RGW)并使用S3访问集群