Leetcode_day01_88合并两个有序数组

Leetcode_day01_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 中。

核心知识点:数组,排序,双指针
解法一:先将数组nums2放入到数组nums1中,然后再排序

class Solution{public void merge(int [] nums1, int m, int [] nums2, int n){for(int i = 0;i != n; ++i){nums1[m + i] = nums2[i];}Arrays.sort(nums1);}
}

时间复杂度:O((m+n)log⁡(m+n)) 【快排】
空间复杂度:O(log⁡(m+n)) 【快排】
在这里插入图片描述

解法二:双指针
这一方法将两个数组看作队列,每次从两个数组头部取出比较小的数字放到结果中。

class Solution{public void merge(int [] nums1, int m, int [] nums2, int n){//定义两个指针int p1 = 0 ,p2 = 0;//存放排好序数据的数组int [] sorted = new int [m + n];int cur;while(p1 < m || p2 < n){// p1 == m nums1没了if(p1 == m){cur = nums2[p2++];// p2 == n nums2没了} 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)。
创建一个中间数组
在这里插入图片描述

解法三:逆向双指针
在解法三的基础上,原地移动,减少空间复杂度的占用。从后向前一次遍历数组,将大的值移动到nums1中的后边。
任意时刻nums1中填入了 (m-p1-1)+(n-p2-1)=m+n-p1-p2-2,nums1中剩余m+n-p1-1
m+n-p1-1 - (m+n-p1-p2-2) = p2 + 1 > 0 因此不会出现覆盖。

class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {//定义指针int p1 = m - 1, p2 = n - 1;//从tail开始依次向前添加元素int tail = m + n - 1;int cur;while (p1 >= 0 || p2 >= 0) {//nums1结束if (p1 == -1) {cur = nums2[p2--];//nums2结束} 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)
空间复杂度:O(1).
在这里插入图片描述
可以看到两种方法的内存占用并没有很大的差距。
chatgbt临时生成了程序来测试一下内存的占用情况:

	public class MergeTest {public static void main(String[] args) {int[] nums1 = {1, 2, 3, 0, 0, 0};int m = 3;int[] nums2 = {2, 5, 6};int n = 3;Runtime runtime = Runtime.getRuntime();// 获取初始内存使用情况long memoryBefore = runtime.totalMemory() - runtime.freeMemory();System.out.println("Initial Memory Usage: " + memoryBefore + " bytes");// 在这里运行你的代码,例如调用代码1的merge方法merge1(nums1, m, nums2, n);     // 获取代码执行后的内存使用情况long memoryAfter = runtime.totalMemory() - runtime.freeMemory();// 计算内存差异long memoryUsed = memoryAfter - memoryBefore;System.out.println("merge1 Memory Used: " + memoryUsed + " bytes");Runtime runtime2 = Runtime.getRuntime();// 获取初始内存使用情况long memoryBefore2 = runtime2.totalMemory() - runtime2.freeMemory();// System.out.println("Initial Memory Usage: " + memoryBefore2 + " bytes");// 在这里运行你的代码,例如调用代码1的merge方法merge2(nums1, m, nums2, n);// 获取代码执行后的内存使用情况long memoryAfter2 = runtime2.totalMemory() - runtime2.freeMemory();System.out.println("merge2 Memory Usage After Execution: " + memoryAfter2 + " bytes");// 计算内存差异long memoryUsed2 = memoryAfter2 - memoryBefore2;System.out.println("Memory Used: " + memoryUsed + " bytes");}public static void merge1(int [] nums1, int m, int [] nums2, int n){//定义两个指针int p1 = 0 ,p2 = 0;//存放排好序数据的数组int [] sorted = new int [m + n];int cur;while(p1 < m || p2 < n){// p1 == m nums1没了if(p1 == m){cur = nums2[p2++];// p2 == n nums2没了} 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];}}public static void merge2(int[] nums1, int m, int[] nums2, int n) {//定义指针int p1 = m - 1, p2 = n - 1;//从tail开始依次向前添加元素int tail = m + n - 1;int cur;while (p1 >= 0 || p2 >= 0) {//nums1结束if (p1 == -1) {cur = nums2[p2--];//nums2结束} else if (p2 == -1) {cur = nums1[p1--];} else if (nums1[p1] > nums2[p2]) {cur = nums1[p1--];} else {cur = nums2[p2--];}nums1[tail--] = cur;}}}

结果:变化太小,看不出来
在这里插入图片描述
有点晚了,有时间再探索一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/599209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS应用开发学习笔记 包名、icon图标,应用名修改 UIAbility组件介绍、UIAbility启动模式、UIAbility组件基本用法

目前HarmonyOS应用主推的是Stage模型开发 一、Stage模型基本概念 项目描述UIAbility组件UIAbility组件是一种包含UI界面的应用组件&#xff0c;主要用于和用户交互。例如&#xff0c;图库类应用可以在UIAbility组件中展示图片瀑布流&#xff0c;在用户选择某个图片后&#xf…

Hotspot源码解析-第十二章-线程栈保护页

了解保护页&#xff0c;先从几个问题开始吧 1、为什么线程栈有栈帧了&#xff0c;还要有保护页&#xff1f; 答&#xff1a;在操作系统中内存可以看成是一个大数组&#xff0c;这就有一个问题&#xff0c;线程之间可能会互相踩了别人的内存空间&#xff0c;所以栈空间也存在这…

空间域图像增强之直方图均衡的python代码实现——冈萨雷斯数字图像处理

原理 直方图&#xff1a; 图像的直方图是一个图像中像素强度值分布的图表。 对于灰度图像&#xff0c;直方图展示了每个灰度级出现的频率。 直方图均衡步骤&#xff1a; 计算累积分布函数&#xff08;CDF&#xff09;&#xff1a;首先&#xff0c;计算图像的直方图&#xff0…

解决:ERROR: Failed building wheel for xxx

解决&#xff1a;ERROR: Failed building wheel for xxx 文章目录 解决&#xff1a;ERROR: Failed building wheel for xxx背景报错问题报错翻译报错原因解决方法参考内容&#xff1a;今天的分享就到此结束了 背景 在使用之前的代码构建环境时&#xff0c;报错&#xff1a;ERRO…

普中STM32-PZ6806L开发板(有点悲伤的故事续-人灯还未了)

简介 继上篇 普中STM32-PZ6806L开发板(有点悲伤的故事) 说到 关于 普中STM32-PZ6806L开发板的LED流水灯也被烧坏掉了&#xff0c;再也无法玩流水灯, 内心充满了只会流水灯的不甘, 流水灯就是单片机的Hello World&#xff0c;怎么能没有呢&#xff1f; 事情发展 好巧不巧想起最近…

Linux操作系统基础(10):Linux的特殊权限

1. 特殊权限是什么 在Linux中&#xff0c;特殊权限是指针对文件或目录的特殊权限设置&#xff0c;包括SetUID、SetGID和Sticky Bit。 SetUID&#xff08;Set User ID&#xff09;&#xff1a; 当一个可执行文件被设置了SetUID权限后&#xff0c;当任何用户执行该文件时&#x…

强大好用的低代码开发工具,yyds!

现在市面上的很多开发工具更侧重代码编辑&#xff0c;针对数据库增删改查&#xff08;CRUD&#xff09;类的Web系统开发&#xff0c;在界面设计、前后端数据交互等环节主要还是靠写代码&#xff0c;效率比较低&#xff1b;而现在市面上很多所谓的低代码开发平台&#xff0c;大多…

服务器经常出现自动重启怎么办

服务器自动重启是一个复杂且常见的问题&#xff0c;可能由多种原因引起。从硬件故障到软件问题&#xff0c;从电源问题到散热问题&#xff0c;每一个环节都可能成为服务器的杀手。在处理此类问题时&#xff0c;需要我们有一套完整的策略和方案&#xff0c;以便快速准确地定位并…

envoy在arm机器上的编译整理

版本信息&#xff1a; 操作系统:GUN Linux操作系统AARCH64架构。istio-proxy版本&#xff1a;istio-proxy1.15.2 编译环境搭建&#xff1a; 设置代理&#xff0c;确保可以访问Google等外网&#xff0c;这里envoy的第一次编译需要从外网下载依赖库。// 备注&#xff1a;这里一定…

决策树--分类决策树

1、介绍 ① 定义 分类决策树通过树形结构来模拟决策过程&#xff0c;决策树由结点和有向边组成。结点有两种类型&#xff1a;内部结 点和叶结点。内部结点表示一个特征或属性&#xff0c;叶子节点表示一个类。 ② 生成过程 用决策树分类&#xff0c;从根结点开始&#xff…

【自学笔记】01Java基础-09Java关键字详解

介绍java&#xff08;基于java11&#xff09;中所有关键字&#xff0c;以及主要重要的关键字详解。 1 Java 11中的关键字&#xff1a; 1.1 类型声明与变量定义 boolean&#xff1a;声明布尔类型变量&#xff0c;只有两个可能值 true 或 false。byte&#xff1a;声明一个8位有…

复制Ubuntu遇到的问题及解决办法、Ubuntu上git命令更改和查看账户、实现Ubuntu与Windows之间的文件共享

1、复制Ubuntu遇到的问题及解决办法 &#xff08;1&#xff09;问题一&#xff1a;“该虚拟机似乎正在使用中。如果该虚拟机未在使用&#xff0c;请按”获取所有权(T)”按钮获取它的所有权。否则&#xff0c;请按”取消(C)”按钮以防损坏。” 出现该问题的原因“未正确关闭虚…

关于java栈和堆

关于java栈和堆 在上一篇文章中我们了解了数组的声明和创建&#xff0c;本篇文章中我们了解一下声明数组&#xff0c;创建数组&#xff0c;给数组赋值以后&#xff0c;栈和堆都是怎么样子分配的&#xff0c;了解一下底层的逻辑知识&#xff0c;让大家可以更好的理解数组&#…

后端中的Dao层、Service层、Impl层、utils层、Controller层

Java Dao层 dao层叫数据访问层&#xff0c;全称为data access object&#xff0c;属于一种比较底层&#xff0c;比较基础的操作&#xff0c;具体到对于某个表、某个实体的增删改查&#xff0c;对外提供稳定访问数据库的方法 Mapper:&#xff08;DAO&#xff09; 访问数据库&am…

新品牌在小红书上宣传推广怎么做?

对于新品牌来说&#xff0c;如何在小红书进行有效的宣传推广&#xff0c;成为了一大挑战。本文伯乐网络传媒将为你揭秘新品牌在小红书上的宣传策略&#xff0c;助你牢牢抓住用户流量&#xff0c;提升品牌知名度。 小红书作为一款以内容为核心的社交电商平台&#xff0c;具有极高…

论文阅读:基于MCMC的能量模型最大似然学习剖析

On the Anatomy of MCMC-Based Maximum Likelihood Learning of Energy-Based Models 相关代码&#xff1a;点击 本文只介绍关于MCMC训练的部分&#xff0c;由此可知&#xff0c;MCMC常常被用于训练EBM。最后一张图源于Implicit Generation and Modeling with Energy-Based Mod…

开发知识点-Java网络编程-Netty

Netty P1 Netty-导学分布式网络返回 异步结果dubbo rabbitmqtest 测试案例多线程 日志 第1章_01_nio三大组件-channel-buffer网络编程 框架jdk 1.4 之后才有 nio这个 APIChannel 数据传输通道 &#xff08;双向&#xff09;Buffer 内存缓冲区 &#xff08;暂存Channel 的 数据&…

【React系列】Redux(三) state如何管理

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. reducer拆分 1.1. reducer代码拆分 我们来看一下目前我们的reducer&#xff1a; function reducer(state ini…

jdk动态代理与cglib代理区别1

动态代理有jdk动态代理及cglib代理&#xff0c;下面描述jdk动态代理 jdk动态代理 看了 上云 老师的视频&#xff0c;整理下 pom文件 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starte…

JS函数实现数字转中文大写

JS函数实现数字转中文大写 1. 数字转字符,分割,去除空字符2. 遍历分割字符,替换为中文3. 增加四位数单位4. 处理零5. 拼接四位数据和单位 项目中,JS将万亿以下正整数转为中文大写 1. 数字转字符,分割,去除空字符 function toChineseNumber(num){const strs num.toString().re…