当前位置: 首页 > 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.xdnf.cn/news/1284895.html

相关文章:

  • 从零开始手搓一个GPT大语言模型:从理论到实践的完整指南(一)
  • 安全合规5--终端安全检测和防御技术
  • MySQL基础面试
  • MySQL 索引优化实战:从执行计划分析到优化策略落地
  • 【狂热算法篇】探寻图论幽径之SPFA算法:图论迷宫里的闪电寻径者(通俗易懂版)
  • 【Unity笔记】视频播放控制器全攻略:支持延迟播放、事件回调与多视频管理的完整实现
  • 数据结构:图
  • 【力扣494】目标和
  • 【代码随想录day 17】 力扣 98.验证二叉搜索树
  • 网站测评-利用缓存机制实现XSS的分步测试方法
  • 正向传播与反向传播(神经网络思维的逻辑回归)
  • 动态规划----1.爬楼梯
  • VUE的8个生命周期
  • 将黑客拒之物联网网络之外的竞赛
  • Openlayers基础教程|从前端框架到GIS开发系列课程(24)openlayers结合canva绘制矩形绘制线
  • Etcd客户端工具Etcd Workbench更新了1.2.0版本!多语言支持了中文,新增了许多快捷功能使用体验再次提升
  • Linux中Apache与Web之虚拟主机配置指南
  • 【门诊进销存出入库管理系统】佳易王医疗器械零售进销存软件:门诊进销存怎么操作?系统实操教程 #医药系统进销存
  • sqli-labs通关笔记-第44关 POST字符型堆叠注入(单引号闭合 手工注入+脚本注入3种方法)
  • 「数据获取」中国高技术产业统计年鉴(1995-2024年)(获取方式看绑定的资源)
  • 文字转语音 edge_tts
  • Docker概述与安装Dockerfile文件
  • 大数据技术入门精讲(Hadoop+Spark)
  • 【密码学】9. 可证明安全
  • 链动 3+1 模式:重构商业增长逻辑的新引擎
  • Mac M1探索AnythingLLM+Ollama+知识库问答
  • 支持任意 MCP 协议的客户端
  • 数据可视化交互深入理解
  • 最终章【1】Epson机器人篇
  • 如何提升需求分析能力