合并两个有序数组

2023-10-29

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

    初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
    你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

示例:

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

输出: [1,2,2,3,5,6]

方法一 : 合并后排序

直觉

最朴素的解法就是将两个数组合并之后再排序。该算法只需要一行(Java是2行),时间复杂度较差,为O((n+m)log⁡(n+m))。这是由于这种方法没有利用两个数组本身已经有序这一点。

//JAVA
class Solution 
{ 
    public void merge(int[] nums1, int m, int[] nums2, int n)
    {
          System.arraycopy(nums2, 0, nums1, m, n); 
          Arrays.sort(nums1); 
    } 
}
#Python
class Solution(object): def merge(self, nums1, m, nums2, n): """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: void Do not return anything, modify nums1 in-place instead.
        """
        nums1[:] = sorted(nums1[:m] + nums2)

方法二 : 双指针 / 从前往后

直觉

一般而言,对于有序数组可以通过 双指针法 达到O(n+m)O(n + m)O(n+m)的时间复杂度。

最直接的算法实现是将指针p1 置为 nums1的开头, p2为 nums2的开头,在每一步将最小值放入输出数组中。

由于 nums1 是用于输出的数组,需要将nums1中的前m个元素放在其他地方,也就需要 O(m)O(m)O(m) 的空间复杂度。

                         

 

//Java
class Solution 
{ 
    public void merge(int[] nums1, int m, int[] nums2, int n)
    { 
        // Make a copy of nums1. 
        int [] nums1_copy = new int[m];
        System.arraycopy(nums1, 0, nums1_copy, 0, m);
        // Two get pointers for nums1_copy and nums2.
        int p1 = 0; 
        int p2 = 0; 
        // Set pointer for nums1 
        int p = 0;
        // Compare elements from nums1_copy and nums2
        // and add the smallest one into nums1.
        while ((p1 < m) && (p2 < n))
            nums1[p++] = (nums1_copy[p1] < nums2[p2]) ? nums1_copy[p1++] : nums2[p2++];
        // if there are still elements to add
        if (p1 < m) 
            System.arraycopy(nums1_copy, p1, nums1, p1 + p2, m + n - p1 - p2);
        if (p2 < n) 
            System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - p1 - p2); 
    } 
}

 

#Python
class Solution(object): 
    def merge(self, nums1, m, nums2, n): 
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: void Do not return anything, modify nums1 in-place instead.
        """ 
        # Make a copy of nums1.
        nums1_copy = nums1[:m] 
        nums1[:] = [] 
        # Two get pointers for nums1_copy and nums2.
        p1 = 0
        p2 = 0 
        # Compare elements from nums1_copy and nums2 # and add the smallest one into nums1.
        while p1 < m and p2 < n: 
            if nums1_copy[p1] < nums2[p2]:
                nums1.append(nums1_copy[p1])
                p1 += 1 
            else:
                nums1.append(nums2[p2]) 
                p2 += 1 
            # if there are still elements to add 
        if p1 < m: 
            nums1[p1 + p2:] = nums1_copy[p1:]
        if p2 < n: 
            nums1[p1 + p2:] = nums2[p2:]

        

 PS:注意最后一种情况容易被忽略

方法三 : 双指针 / 从后往前

直觉

方法二已经取得了最优的时间复杂度O(n+m)O(n + m)O(n+m),但需要使用额外空间。这是由于在从头改变nums1的值时,需要把nums1中的元素存放在其他位置。

    如果我们从结尾开始改写 nums1 的值又会如何呢?这里没有信息,因此不需要额外空间。

这里的指针 p 用于追踪添加元素的位置。

                

                      

                      

                      

                       

//JAVA
class Solution 
{ 
	public void merge(int[] nums1, int m, int[] nums2, int n)
	{
		// two get pointers for nums1 and nums2
		int p1 = m - 1; 
		int p2 = n - 1;
		// set pointer for nums1 
		int p = m + n - 1;
		// while there are still elements to compare 
		while ((p1 >= 0) && (p2 >= 0)) 
			// compare two elements from nums1 and nums2 
			// and add the largest one in nums1 
			nums1[p--] = (nums1[p1] < nums2[p2]) ? nums2[p2--] : nums1[p1--]; 
		// add missing elements from nums2 
		System.arraycopy(nums2, 0, nums1, 0, p2 + 1); 
	} 
}
#Python
class Solution(object): def merge(self, nums1, m, nums2, n): """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: void Do not return anything, modify nums1 in-place instead.
        """ 
        # two get pointers for nums1 and nums2 
        p1 = m - 1 
        p2 = n - 1 
        # set pointer for nums1 
        p = m + n - 1 
        # while there are still elements to compare 
        while p1 >= 0 and p2 >= 0: 
            if nums1[p1] < nums2[p2]:
                nums1[p] = nums2[p2] p2 -= 1
            else:
                nums1[p] = nums1[p1] 
                p1 -= 1
                p -= 1 
        # add missing elements from nums2 
        nums1[:p2 + 1] = nums2[:p2 + 1]

PS :注意最后一种情况 

 

 

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

合并两个有序数组 的相关文章

  • 数组排序(C 语言实现)

    本文主要包含常见的数组排序方法 选择排序 原理 在原始数组中取未排序的首元素 xff0c 与其后方所有元素比较 xff0c 不满足顺序 xff0c 则交换首元素此时满足条件 xff0c 未排序部分后移重复上述操作 代码实现 include
  • javascript数组排序

    javascript原生排序算法sort xff0c 如果不带排序函数 xff0c 那么就是默认按照升序排列 如果是数字类型就按照从小到大的顺序排列 xff0c 如果是字符串 xff0c 就按照字母顺序排列 Sorts an array i
  • C语言---数组排序

    1 冒泡排序 xff08 从后往前 xff09 1 比较相邻的元素 如果第一个比第二个大 xff0c 就交换他们两个 2 对每一对相邻元素作同样的工作 xff0c 从开始第一对到结尾的最后一对 在这一点 xff0c 最后的元素应 该会是最大
  • Unity中射线Ray和RaycastHit的简单介绍

    射线是在三维世界中从一个点沿一个方向发射的一条无限长的线 在射线的轨迹上 一旦与添加了碰撞器的模型发生碰撞 将停止发射 我们可以利用射线实现子弹击中目标的检测 鼠标点击拾取物体等功能 1 Physics Raycast public sta
  • 自学中走出的大三学生面临就业选择

    来信 贺老师您好 这是我第二次向您请教问题了 非常感谢您上次给我的建议 注 上次来信见http blog csdn net sxhelijian article details 7760011 如邮件主题所述 我是一个即将大四的学生 我学的
  • 自学微信小程序开发第九天-关于分包

    自学微信小程序开发第九天 关于分包 分包前后的项目构成 分包的加载规则 文件分配 分包的配置定义 分包的一些原则 打包原则 引用原则 分包举例 独立分包 独立分包的应用场景举例 声明独立分包 进入独立分包页面 分包预下载 分包指的是把一个完
  • 关于Unity中的NGUI和UGUI

    一 用Unity开发2D游戏 有三套关系 1 GUI Unity本身自带的GUI 2 NGUI 以前在Unity中广泛来做2D的 是第三方的包 需要安装 3 UGUI Unity5 X后 其实是Unity4 6以后 Unity找到NGUI的
  • Unity Android手机触屏事件

    一 下面先说经常用的三个事件 手指按下 手指移动 手指松开 1 手指按下 if input touchCount 1 if input touches 0 phase TouchPhase Beagn 手指按下时 要触发的代码 2 手指在屏
  • Java中方法的学习

    目录 Java中的方法定义 设计方法的原则 方法的命名规则 代码实现 方法调用 方法的重载 方法学习不知死过多少次 还让我学是吧 你没完了哈 来 来 来 咱们一起来分析 老师 前面的关键字我讲过吧 数据类型还用说嘛 方法的定义格式我说过吧
  • Linux应用开发自学之路

    前言 在 关于我 那篇博文里 朋友们应该知道了我不是科班出身 是由机械强行转行到Linux应用开发方向 下面我就详细向大家介绍自己这一路上的转行历程 希望对大家有所启发 我是学机械专业的 对于机械专业我还是很感兴趣 而且当年这个专业也是我自
  • unity3d 给模型添加刚体后、或者角色控制器后下坠

    1 给模型添加一个刚体后 还要给模型添加一个碰撞器 人和地面的话 要注意地面有没有碰撞器 有的话注意地面碰撞器的Mesh网格是不是Null 还有
  • Unity角色控制器CharacterController的简单介绍

    角色控制器 CharacterController 首先 角色控制器没有碰撞效果 这是和刚体的区别 不像刚体可以给其力 如果想使人物移动 直接复制官方文本中的CharacterController下的Move 方法 前台添加 Charact
  • 微信公众号测试号url和token绑定失败解决问题

    前提准备 在本地搭建一个本地服务器 具体查看如何搭建一个本地服务器 首先 我们需要到natapp获取一个信道 博主这里买的是vip1型的 当然也可以使用免费型的 根据需要选择 完了之后 去 我的隧道 查看购买的信道 复制里面的authtok
  • js数组的顺序排序、完全随机打乱排序 总结

    一 顺序排序 1 按字符编码排序 sort var testArray 23 500 1000 300 34 2 testArray sort alert testArray 2 1000 23 300 34 500 2 将数组元素倒序排
  • Java语言的重载和重写的区别

    学习java语言中重载和重写的区别 重载 Overload 重载 overloading 是在一个类里面 方法名字相同 而参数不同 返回类型可以相同也可以不同 每个重载的方法 或者构造函数 都必须有一个独一无二的参数类型列表 最常用的地方就
  • unity UGUI之Button按钮多种触发方式实现(有参无参函数)

    UGUI之Button按钮有多种触发方式 下面讲两种 第一种方法是在依靠属性面板绑定物体然后找到物体脚本上的方法触发 第二种是用纯代码的方式是用onClick方法 第一种 首先建立一个button 之后看button属性 如图右下角 那里的
  • python学习笔记(一)---第一个python程序

    1 Windows CMD命令 cd 文件夹名称 进入指定文件夹 dir 查看当前目录下的文件 2 python的运行 在命令行敲入pthon 进入python交互模式 交互模式下的提示符是 gt gt gt 然后就可以敲代码 如print
  • Unity3D UNET 模仿局域网游戏(二)

    紧接着上一篇博客 上一篇博客中 我们已经能够分别移动角色 并且控制他射击了 而且还稍微区分了一下不同的角色 这篇博客中我们继续讲解后面的内容 既然角色都已经可以射击了 那肯定还得需要一个血量对吧 所以现在我们就添加血量 给Player添加H
  • [UnityUI]UGUI自适应

    关键点 0 自适应的测试 通过设置多种的屏幕大小进行测试 测试时最好要打开Maximize on Play 在屏幕放大的情况下容易观察自适应情况 1 所谓的自适应 就是 a 保持相对位置不变 例如UI设计在屏幕的左上角 那么在各种的分辨率下
  • Unity3D之触摸输入实现物体滑动

    新建一个Cube物体 创建一个脚本TouchTest04 将该脚本挂到Cube物体上 代码如下 csharp view plain copy using UnityEngine using System Collections public

随机推荐

  • 修复VMware网络连接失败及设置固定IP

    最近被这个网络折磨疯了 记录一下怎么修复虚拟机网路连接 VM软件安装好后 就有10个网络连接类型可供选择 分别是 VMnet0 VMnet1 VMnet2 VMnet3 VMnet4 VMnet5 VMnet6 VMnet7 VMnet8
  • 数据库操作:汇总数据(聚集函数)

    我们经常需要汇总数据而不用把它们实际检索出来 为此MySQL提供了专门的函数 聚集函数运行在行组上 计算和返回单个值的函数 SQL聚集函数 1 AVG 返回某列的平均值 2 COUNT 返回某列的行数 3 MAX 返回某列的最大值 4 MI
  • java数组及数组函数

    数组求和 1 System out println 1 2 3 4 5 getSum 1 2 3 4 5 5个参数 public static int getSum int numbers 可变长形参 本质为数组 int sum 0 for
  • 服务器系统要用GUID还是MBR,分享win10分区格式MBR和GUID有什么区别 教你区分MBR和GUID格式...

    今天IT天空小编要给大家分享下最新的教程 电脑装win10系统需要选择正确的分区格式 这样电脑才能保持正常运转 如果格式安装错误 电脑就没办法继续运行了 一般情况下 win10分区格式MBR和GUID两种选择 那么这两者有何区别 电脑小白肯
  • 华为ensp,实战案例一一使用模拟器构建局域网络

    1 案例目标 I 通过组网设计 掌握小型网络的组建 路由的设计 对小型网络系统进行分析 提出建网解决方案 2 综合运用路由 VLAN的相关技术 3 综合运用VLAN创建 Access和Trunk接口配置 VLAN间路由配置 DHCP 也址池
  • 民族代码设计

    民族代码和对应民族名称 在开发时 设计民族的数据字典 民族代码 民族名称 01 汉族 01 汉族 02 蒙古族 03 回族 04 藏族 05 维吾尔族 06 苗族 07 彝族 08 壮族 09 布依族 10 朝鲜族 11 满族 12 侗族
  • 基于遗传算法的BP神经网络优化算法(matlab实现)

    1 理论基础 1 1 BP神经网络概述 BP网络是一类多层的前馈神经网络 它的名字源于在网络训练的过程中 调整网络的权值的算法是误差的反向传播的学习算法 即为BP学习算法 BP算法是Rumelhart等人在1986年提出来的 由于它的结构简
  • Scanner 类

    目录 1 什么是Scanner类 2 创建Scanner类的基本语法 3 使用next方法 4 使用nextLine方法 5 next 与nextLine 6 数据类型的接收方式 7 Scanner类知识扩展 8 今日箴言 1 什么是Sca
  • JAVA代码规范

    一 MyBatis 不要为了多个查询条件而写 1 1 二 迭代entrySet 获取Map 的key 和value 三 使用Collection isEmpty 检测空 四 初始化集合时尽量指定其大小 五 若需频繁调用Collection
  • C++之I/0流操作(标准流、文件流、二进制操作等)

    目录 标准输入输出 文本文件输入输出 文件类型 文件打开方式 写文件 读文件 二进制文本输入输出 写文件 读文件 字符串输入输出 往流里面输出 从流里面读出 格式控制 流 stream 为C 的输入输出操作提供了许多的便利 通常我们使用的流
  • Django(9)-表单处理

    django支持使用类创建表单实例 polls forms py from django import forms class NameForm forms Form your name forms CharField label Your
  • 面试准备:Mybatis常见面试题汇总

    文章目录 1 和 的区别是什么 2 当实体类中的属性名和表中的字段名不一样 怎么办 3 模糊查询like语句该怎么写 4 Mybatis 一对一 一对多的xml怎么写 5 Dao 接口的工作原理是什么 Dao 接口里的方法 参数不同时 方法
  • Python中函数,类,模块,包,库的区别

    文章目录 关系图 参考文章 关系图 参考文章 借鉴了以下文章 Python中函数 类 模块 包 库的区别 一分钟带你分清Python的模块 包和库的区别 python中的模块 库 包有什么区别
  • c# 保存软件配置

    保存配置方法 一 Settings setting 文件 1 1 配置Settings settings文件 1 2 加载配置信息 1 3 保存配置信息 二 使用文本保存 2 1 引入命名空间 2 2 新增IniConfigHelper 类
  • 装win10提示“在EFI系统上,Windows只能安装到GPT磁盘”

    在安装界面 按 shift F10 键 在命令提示符窗口依次执行如下命令 输入 diskpart 命令后 按enter键 进入到 DISKPART 模式 输入 list disk 命令后 按enter键 查看电脑的硬盘 编号0 表示电脑的第
  • 【python文本分析】——基于股评文本的情绪分析

    目录 一 文本处理 1 精确模式 默认 2 全模式 3 搜索引擎模式 二 词云图 1 wordcloud模块导入 2 词云图实现 三 实例 利用股评进行情绪分析 1 数据来源及snownlp模块导入 2 代码实现 2 1 读取股评文件 2
  • windows 10 安装子系统(WSL2)

    以前在学习docker时 是在自己的虚拟机上进行的 最近刚换了电脑 想在windows中使用子系统来运行docker 现在WSL2要比以前的WSL1运行更快 io操作方面的很大的提升 在这里记录一下我的安装过程吧 希望小白们有些参考 关注微
  • 【使用mindspore复现segmenter语义分割算法时,loss一直在一个范围内附近波动,降不下去】

    使用mindspore复现segmenter语义分割算法 操作步骤 问题现象 1 即使训练了很多个epoch 精度一直下降不了 一直在1 2左右 测试出来的miou也是一个非常低的值 例如0 0198 2 目前尝试过不同的优化器SGD AD
  • 腾讯mini项目-【指标监控服务重构】2023-07-27

    今日已办 SigNoz Log Management SigNoz原生支持 OpenTelemetry 来收集日志 SigNoz 在收集器端进行了优化 为SigNoz中的日志添加了不同的功能 OpenTelemetry 提供了各种接收器和处
  • 合并两个有序数组

    给定两个有序整数数组 nums1 和 nums2 将 nums2 合并到 nums1 中 使得 num1 成为一个有序数组 说明 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 你可以假设 nums1 有足够的空间 空间大