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

【LeetCode刷题日志】88.合并两个有序数组

  • 🎈个人主页:库库的里昂
  •  🎐C/C++领域新星创作者
  •  🎉欢迎 👍点赞✍评论⭐收藏
  • ✨收录专栏:LeetCode 刷题日志
  • 🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗

目录

1.题目描述

2.解题思路+代码实现

方法一:直接合并后排序

思路及算法:

代码实现:

方法二:双指针

思路及算法:

代码实现:

方法三:逆向双指针

思路及算法:

代码实现:


1.题目描述

OJ链接 【leetcode 题号:88.合并两个有序数组】【难度:简单】

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。

示例 3:

输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示:

  • nums1.length == m + n
  • nums2.length == n
  • 0 <= m, n <= 200
  • 1 <= m + n <= 200
  • -109 <= nums1[i], nums2[j] <= 109

进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?

2.解题思路+代码实现

方法一:直接合并后排序
思路及算法:

这种方法最直观,先将数组nums2放进数组nums1的尾部,然后直接对整个数组进行排序。

代码实现:
int cmp(int* a, int* b) {return *a - *b;
}void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {for (int i = 0; i != n; ++i) {nums1[m + i] = nums2[i];}qsort(nums1, nums1Size, sizeof(int), cmp);
}

复杂度分析

  • 时间复杂度:O((m+n)log(m+n))。 排序序列长度为m+n,套用快速排序的时间复杂度即可,平均情况为O((m+n)log(m+n))。
  • 空间复杂度:O(log(m+n))。排序序列长度为m+n,套用快速排序的空间复杂度即可,平均情况为O(log⁡(m+n))。
方法二:双指针
思路及算法:

方法一没有利用数组nums1nums2已经被排序的性质。为了利用这一性质,我们可以使用双指针方法。这一方法将两个数组看作队列,每次从两个数组头部取出比较小的数字放到结果中。如下面的动画所示:

我们为两个数组分别设置一个指针p1​与p2​来作为队列的头部指针。

代码实现:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int p1 = 0, p2 = 0;int sorted[m + n];int cur;while (p1 < m || p2 < n) {if (p1 == m) {cur = nums2[p2++];} else if (p2 == n) {cur = nums1[p1++];} else if (nums1[p1] < nums2[p2]) {cur = nums1[p1++];} else {cur = nums2[p2++];}sorted[p1 + p2 - 1] = cur;}for (int i = 0; i != m + n; ++i) {nums1[i] = sorted[i];}
}

复杂度分析

  • 时间复杂度:O(m+n)。 指针移动单调递增,最多移动m+n次,因此时间复杂度为O(m+n)。
  • 空间复杂度:O(m+n)。 需要建立长度为m+n的中间数组sorted。
方法三:逆向双指针
思路及算法:

方法二中,之所以要使用临时变量,是因为如果直接合并到数组nums1中,nums1中的元素可能会在取出之前被覆盖。那么如何直接避免覆盖nums1中的元素呢?观察可知,nums1的后半部分是空的,可以直接覆盖而不会影响结果。因此可以指针设置为从后向前遍历,每次取两者之中的较大者放进nums1的最后面。

严格来说,在此遍历过程中的任意一个时刻,nums1数组中有m−p1−1个元素被放入nums1的后半部,nums2数组中有n−p2−1个元素被放入nums1的后半部,而在指针p1的后面,nums1数组有 m+n−p1−1个位置。由于

m+n−p1−1≥m−p1−1+n−p2−1等价于p2≥−1

永远成立,因此p1后面的位置永远足够容纳被插入的元素,不会产生p1的元素被覆盖的情况。

代码实现:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int p1 = m - 1, p2 = n - 1;int tail = m + n - 1;int cur;while (p1 >= 0 || p2 >= 0) {if (p1 == -1) {cur = nums2[p2--];} else if (p2 == -1) {cur = nums1[p1--];} else if (nums1[p1] > nums2[p2]) {cur = nums1[p1--];} else {cur = nums2[p2--];}nums1[tail--] = cur;}
}

复杂度分析

  • 时间复杂度:O(m+n)。 指针移动单调递减,最多移动m+n次,因此时间复杂度为 O(m+n)。
  • 空间复杂度:O(1)。 直接对数组nums1原地修改,不需要额外空间。

相关文章:

【LeetCode刷题日志】88.合并两个有序数组

&#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;C/C领域新星创作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;LeetCode 刷题日志&#x1f91d;希望作者的文章能对你有所帮助&#xff0c;有不足的地方请在评论区留言指正&#xff0c;…...

计算机考研 | 2013年 | 计算机组成原理真题

文章目录 【计算机组成原理2013年真题43题-9分】【第一步&#xff1a;信息提取】【第二步&#xff1a;具体解答】 【计算机组成原理2013年真题44题-14分】【第一步&#xff1a;信息提取】【第二步&#xff1a;具体解答】 【计算机组成原理2013年真题43题-9分】 某32位计算机&a…...

[Unity][VR]透视开发系列4-解决只看得到Passthrough但看不到Unity对象的问题

【视频资源】 视频讲解地址请关注我的B站。 专栏后期会有一些不公开的高阶实战内容或是更细节的指导内容。 B站地址: https://www.bilibili.com/video/BV1Zg4y1w7fZ/ 我还有一些免费和收费课程在网易云课堂(大徐VR课堂): https://study.163.com/provider/480000002282025/…...

电气工程 自动化 机械工科学生来看看

PLC 类 基于PLC的机械手控制系统设计 基于PLC的机械手控制系统设计 PLC与变频器在综采设备上的应用 PLC与步进电机的运动控制编程9000 PLC应用数字电子钟设计 三菱FX系列PLC与三菱变频器通讯应用实例 基于plc拉杆箱振动与噪音检测平台设计 基于PLC的船舶空压机控制系统设计 基…...

NewStarCTF2023week4-midsql(利用二分查找实现时间盲注攻击)

大致测试一下&#xff0c;发现空格被过滤了 使用内联注释/**/绕过&#xff0c;可行 1/**/-- 使用%a0替代空格&#xff0c;也可以 1%a0-- 再次测试发现等号也被过滤&#xff0c;我们使用 like 代替 &#xff08;我最开始以为是and被过滤&#xff0c;并没有&#xff0c;如果是…...

null,undefined的区别?

在 JavaScript 中,null 和 undefined 都表示没有值或缺失值的状态,但它们之间有一些区别。 null: null 是一个表示空值的特殊关键字。它是一个表示变量未赋值的值,可以将其赋给任何变量,表示该变量为空。使用 null 可以明确地将一个变量设置为空。 示例: let myVaria…...

2.flink编码第一步(maven工程创建)

概述 万里第一步&#xff0c;要进行flink代码开发&#xff0c;第一步先整个 flink 代码工程 flink相关文章链接 flink官方文档 两种方式 一种命令行 mvn 创建&#xff0c;另一种直接在 idea 中创建一个工程&#xff0c;使用 mvn 的一些配置 mvn命令行创建 mvn 创建flink工程&…...

Unit1_1:分治问题之时间复杂度求解

文章目录 背景递归树法案例一案例二局限性 代入法/替代法主方法&#xff08;重点&#xff09; 背景 当碰到形如 T ( n ) a T ( ⌈ n b ⌉ ) O ( n d ) T(n)aT(\lceil \frac{n}{b} \rceil)O(n^d) T(n)aT(⌈bn​⌉)O(nd)的递推式&#xff0c;本质上就是将问题转化为规模更小的…...

React hooks的闭包陷阱

react hooks 陷阱 hooks必须放在函数顶层&#xff0c; 不能在条件分支和方法内 1、useState陷阱 异步陷阱 function Index() {const [count, setCount] useState(0)function add(){setCount( count 1 )console.log(count); // 0}return (<div><span>{count}…...

20.3 OpenSSL 对称AES加解密算法

AES算法是一种对称加密算法&#xff0c;全称为高级加密标准&#xff08;Advanced Encryption Standard&#xff09;。它是一种分组密码&#xff0c;以128比特为一个分组进行加密&#xff0c;其密钥长度可以是128比特、192比特或256比特&#xff0c;因此可以提供不同等级的安全性…...

一文详解防御DDoS攻击的几大有效办法

伴随互联网的飞速发展&#xff0c;网络安全问题变得越来越突出&#xff0c;其中最常见的就是DDoS攻击&#xff0c;也就是分布式拒绝服务攻击。DDoS攻击者利用计算机或其他设备的协作&#xff0c;以发送大量请求的方式导致目标超负荷&#xff0c;导致不能正常运转或“宕机”。以…...

Python二级 每周练习题24

练习一: 体重比较器 要求: 请编程实现如下功能: (1)程序开始运行时&#xff0c;提醒用户输入三个人的名字和体重 (可以分开输入&#xff0c;每次输入名字或者体重) (2) 程序自动比较&#xff0c;找出最重的一个人的名字和体重输出 的格式不限&#xff0c;但是要有最重人的姓名…...

MySQL - Buffer Pool

Buffer Pool 主要用于缓存数据库表的数据页&#xff0c;以提高数据库的读取性能&#xff1a; 缓存数据页&#xff1a;Buffer Pool 是 MySQL 中用于缓存数据页的内存区域。数据页通常包含数据库表的数据&#xff0c;如行记录等。当查询或读取数据时&#xff0c;MySQL会首先查看…...

c++ 拆分函数返回值和参数类型

在c中&#xff0c;函数参数类型和返回值类型通常是一个比较明确的信息&#xff0c;好像确实无需在这个上面费周折。然而&#xff0c;硬编码数据类型会让代码复用性下降&#xff0c;如果能够通过某种方式自动获取函数参数和返回值类型&#xff0c;对于代码的可复用性&#xff0c…...

Ubuntu 23.10安装TeXlive并安装CTEX中文支持

连接上互联网&#xff0c;打开SHELL命令行界面&#xff0c; 1. sudo apt install texlive texstudio texlive-lang-chinese 就可以安装好了。texlive-lang-chinese 是TEXLIVE对CTEX中文的支持。 2. Tex源文件必须采用UTF-8编码格式&#xff0c;编译器采用xelatex。这样对中文…...

SpringBoot中CommandLineRunner详解(含源码)

文章目录 前言实例导入库application.yamlRunnerSpringBootCommandLineRunnerApplication执行结果 先后顺序示例OrderRunner1OrderRunner2执行结果 通常用法加载初始化数据示例 启动后打印应用信息示例 启动异步任务示例 接口健康检查示例 外部服务调用示例 参数校验示例 动态设…...

通信基础(一):数据传输基础

一、波特率与比特率关系 比特率(信息传输速率、信息速率):指单位时间内在信道上传 送的数据量(即比特数),单位为比特每秒 (bit/s), 简记为b/s或bps。 波特率与比特率有如下换算关系&#xff1a; bitbaud *log 2(N) 其中&#xff0c; N是码元总类数。 特别注意&#xff…...

故障诊断模型 | Maltab实现BiLSTM双向长短期记忆神经网络故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现BiLSTM双向长短期记忆神经网络故障诊断 模型描述 利用各种检查和测试方法,发现系统和设备是否存在故障的过程是故障检测;而进一步确定故障所在大致部位的过程是故障定位。故障…...

物联网和互联网医院小程序:如何实现医疗设备的远程监测和管理?

物联网&#xff08;IoT&#xff09;技术的发展为医疗设备的远程监测和管理提供了巨大的机会。结合互联网医院小程序&#xff0c;我们可以实现对医疗设备的远程访问、监控和管理&#xff0c;从而提高医疗服务的质量和效率。本文将介绍如何实现医疗设备的远程监测和管理&#xff…...

sharepoint2016-2019升级到sharepoint订阅版

一、升级前准备&#xff1a; 要建立新的sharepoint订阅版环境&#xff0c;需求如下&#xff1a; 1.单服务器硬件需求CPU 4核&#xff0c;内存24G以上&#xff0c;硬盘300G&#xff08;根据要迁移的数量来扩容大小等&#xff09;&#xff1b; 2.操作系统需要windows server 20…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…...