两个非递减顺序表合并成一个非递减顺序表

news/2024/11/29 11:34:39/

两个非递减顺序表合并成一个非递减顺序表

  • 引入

以下这个例题的描述是关于合并两个有序的数组,然后合并之后同样也是一个非递减的顺序排列

但是我名这里讲的不是顺序表,而是封装成一个顺序表,但是我们这里的顺序表其实底层同样是一个数组,所以解题的思路完全相同,我们接下来要讲的就是“两个非递减顺序表合成的一个非递减的顺序表”。


合并两个有序数组

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


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


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

  • 我们是合并两个顺序表,只是多了一个封装顺序表的步骤,但是该题目的解法思路是大同小异的。

❤️理清思路

  • 非递减顺序表

    非递减就是 “”,而顺序表就是线性表的一种,其逻辑结构是顺序结构,同时其物理结构也和逻辑结构相同的结构,在计算机中存储的物理结构也是连续存储的。

  • 题目要求

    将两个 “非递减顺序表” 合成一个非递减的顺序表,那么我们在实现这个方法的时候需要传两个 “非递减顺序表”作为参数,然后我们就在方法中对这两个顺序表进行操作。并且最后合成的顺序表同样非递减的顺序表,那么我们在实现方法的时候就必须保证顺序表的顺序一致

  • 思路

    自定义一个"顺序表"数据结构,然后定义一个方法 merge (),这个方法要求是传进去两个“非递减的顺序表对象” 参数,分别是 list 1 和 list 2;然后我们在方法中重新 new 一个“新的非递减的顺序表对象”newList,然后定义三个指针分别指向这三个顺序表下标为 0 的位置,利用“穿针引线法”,完成合并工作。

  • 穿针引线法

    我在这里将这种方式描述为 "穿针引线法"是因为真的很形象,但是其实如果是在链表中这样称呼,似乎更加合适。

    我们分别让 i 和 j 永远指向即将进行比较大小的数据元素,然后让 k 在新顺序表中永远都指向“索引等于顺序表有效长度“ 的地方,然后等待 i 和 j 比较的结果的数据元素的插入,直到任意一个顺序表遍历完,
    如果同时遍历完, 那么合并的工作做完了;如果其中一个顺序表遍历玩,而另外一个没有遍历完,那么就把更长的顺序表直接加到 newList 顺序表中。
    综上所述,就完成了两个非递减顺序表的合并工作。


🚀代码实现

package TextReport;  import java.util.Arrays;  public class MyArrayList {  //    存放数据的数组  public int[] elem;  //    记录数组的有效长度  public int usedSize;  //    常量,用来给数组初始化容量  public static final int DEFAULT_CAPACITY = 5;  //    构造方法  public MyArrayList() {  this.elem = new int[DEFAULT_CAPACITY];  }  public MyArrayList(int defaultSize) {  this.elem = new int[defaultSize];  }  //    打印顺序表的方法(顺序表中有几个有效元素就打印几个有效元素)  public void display() {  for (int i = 0; i < usedSize; i++) {  System.out.print(this.elem[i] + " ");  }  System.out.println();  }  //    输入(新增加元素,默认在顺序表的最后一个元素的下一个位置上新增)  public void add(int data) {  try {  if (isFull()) {  elem = Arrays.copyOf(elem, 2 * elem.length);  }  } catch (NegativeArraySizeException e) {  e.printStackTrace();  }  Elem[usedSize++] = data;  }  //    在指定位置索引为 pos 新增元素  Public void addPos (int data, int pos) {  //先判断下标是否合法  Try {  CheckedAddPos (pos);  If (isFull ()) {  Elem = Arrays.CopyOf (elem, 2 * elem. Length);  }  For (int i = usedSize - 1; i > pos; i--) {  Elem[i + 1] = elem[i];  }  Elem[pos] = data;  UsedSize++;  } catch (PosIndexIllegalException e) {  e.getMessage ();  }  }  //判断顺序表中是否包含某个元素  Public boolean contains (int data) {  For (int i = 0; i < usedSize; i++) {  If (data == elem[i]) {  Return true;  }  }  Return false;  }  //返回某个元素的在容器中的索引  Public int indexOf (int find) {  For (int i = 0; i < usedSize; i++) {  If (find == elem[i]) {  Return i;  }  }  Return -1;  }  //获取指定下标 pos 的值  Public int getPos (int pos) {  Int retVal = -1;  //检查 pos 是否合法  Try {  CheckGetPos (pos);  RetVal = elem[pos];  ;  } catch (PosIndexIllegalException e) {  e.getMessage ();  }  Return retVal;  }  //      删除第一次出现关键字 key 的方法  Public void remove (int key) {  //先获取第一次出现 key 元素的下标  Int index = indexOf (key);  If (index == -1) {  System.Out.Println ("没有找到你要删除的数据!");  Return;  }  For (int i = index; i < usedSize - 1; i++) {  Elem[i] = elem[i + 1];  }  UsedSize--;  }  /**  * removeAll 方法删除整个顺序表  */  Public void removeAll () {  Elem = new int[5];  UsedSize = 0;  }  //    判满方法  Private boolean isFull () {  Return usedSize == elem. Length;  }  //    判断顺序表的下标是否合法  Private void checkedAddPos (int pos) {  if (pos < 0 || pos > usedSize) {  Throw new PosIndexIllegalException ();  }  }  //   判断下标 pos 是否合法  Private boolean checkGetPos (int pos) {  if (pos < 0 || pos >= usedSize) {  Return false;  }  Return true;  }  /**  * 获取顺序表的个数  *  * @return 返回数组的大小  */  Public int size () {  Return usedSize;  }  }  Class PosIndexIllegalException extends RuntimeException {  Public PosIndexIllegalException () {  }  Public PosIndexIllegalException (String msg) {  Super (msg);  }  
}

🍔测试程序

我们是在外部的程序 MyArrayListTest 中进行的测试,先准备两个顺序表,然后调用 merge 方法,并把两个参数传进去,然后会返回一个顺序表,我们再继续调用我们封装的 MyArrayList 类当中的 display 方法。

Package TextReport;  Public class MyArrayListTest {  Public static void main (String[] args) {  //准备两个顺序表(非递减的顺序表)  MyArrayList myArrayList 1 = new MyArrayList ();  MyArrayList 1.Add (1);  MyArrayList 1.Add (5);  MyArrayList 1.Add (10);  MyArrayList 1.Add (13);  MyArrayList 1.Display ();  ;  MyArrayList myArrayList 2 = new MyArrayList ();  MyArrayList 2.Add (6);  MyArrayList 2.Add (11);  MyArrayList 2.Add (12);  MyArrayList 2.Add (33);  MyArrayList 2.Add (44);  MyArrayList 2.Add (47);  MyArrayList 2.Add (52);  MyArrayList 2.Add (66);  MyArrayList 2.Display ();  ;  //调用 merge 方法  MyArrayList mergeArrayList = merge (myArrayList 1, myArrayList 2);  //调用 display 方法  MergeArrayList.Display ();  }  /**  * 合并两个升序的非递减顺序表,并返回新的合成的顺序表  *  * @param list 1 按值非递减顺序表一  * @param list 2 按值非递减顺序表二  * @return 返回一个新的合并了的链表  */  Public static MyArrayList merge (MyArrayList list 1, MyArrayList list 2) {  MyArrayList newList = new MyArrayList (50);  Int i = 0, j = 0;  While (i < list 1.Size () && j < list 2.Size ()) {  If (list 1. Elem[i] < list 2. Elem[j]) {  NewList. Elem[newList. UsedSize] = list 1. Elem[i];  I++;  NewList. UsedSize++;  } else {  NewList. Elem[newList. UsedSize] = list 2. Elem[j];  J++;  NewList. UsedSize++;  }  }  While (i < list 1.Size ()) {  NewList. Elem[newList. UsedSize] = list 1. Elem[i];  I++;  NewList. UsedSize++;  }  While (j < list 2.Size ()) {  NewList. Elem[newList. UsedSize] = list 2. Elem[j];  NewList. UsedSize++;  J++;  }  Return newList;  }  
}

🥰测试结果

在这里插入图片描述


💗图文并茂

该图片是合并结束之后的图示,可以形象的看清楚 i ,j,k 这三个“指针是如何“行走的”。
注意:k 下标其实是 usedSize,是顺序表中的用来表示顺序表的有效长度。

在这里插入图片描述


🎊视频演示

这个视频简单的演示了我当前举的这个例子是如何进行合并的过程,时常两分钟,希望可以看完,这样可以更好的理解 “如何合并两个非递减的顺序表”。

两个非递减顺序表合并视频演示


点赞+收藏+关注💕
请添加图片描述


http://www.ppmy.cn/news/1086654.html

相关文章

渗透测试——安全漏洞扫描工具APPScan的安装与基本使用步骤

前言 HCL AppScan Standard是安全专家和渗透测试者设计的动态应用程序安全测试工具&#xff0c;AppScan使用强大的扫描引擎&#xff0c;会自动检索目标应用程序并测试漏洞。测试结果按优先级排列&#xff0c;允许操作员快速分类问题、发现最关键的漏洞。每个检测到的问题都可以…

电源模块的降额曲线

大家好&#xff0c;这里是大话硬件。 今天想写这篇文章来分享在前段时间了解的一个知识点——电源模块的降额曲线。 为什么要写这个呢&#xff1f;对于专门做电源的同学来说&#xff0c;肯定觉得很简单。但是对于一个非电源行业的人来说&#xff0c;曲线应该如何解读&#xff…

Large Language Models and Knowledge Graphs: Opportunities and Challenges

本文是LLM系列的文章&#xff0c;针对《Large Language Models and Knowledge Graphs: Opportunities and Challenges》的翻译。 大语言模型和知识图谱&#xff1a;机会与挑战 摘要1 引言2 社区内的共同辩论点3 机会和愿景4 关键研究主题和相关挑战5 前景 摘要 大型语言模型&…

Doris-1.2.6集群

1、系统软件 1.1 、系统版本 系统&#xff1a;centos 7.1及以上&#xff1b;Ubuntu 16.04及以上 软件&#xff1a;Java 1.8及以上&#xff1b;GCC 4.8.2及以上&#xff1b; 1.2、环境检查 1.2.1、gcc安装 1、Centos ansible cluster -m shell -a "yum -y install gc…

J. Med. Chem 2022|TocoDecoy+: 针对机器学习打分函数训练和测试的无隐藏偏差的数据集构建新方法

原文标题&#xff1a;TocoDecoy: A New Approach to Design Unbiased Datasets for Training and Benchmarking Machine-Learning Scoring Functions 论文链接&#xff1a;https://pubs.acs.org/doi/10.1021/acs.jmedchem.2c00460 论文代码&#xff1a;GitHub - 5AGE-zhang/T…

基于体系结构架构设计-架构真题(十五)

基于体系结构开发设计&#xff08;Architecture-Base Software Design&#xff09;ABSD&#xff0c;是指构成体系结构的&#xff08;&#xff09;组合驱动&#xff0c;ABSC方法是一个自项向下、递归细化的方法&#xff0c;软件系统的体系结构通过该方法细化&#xff0c;直到能产…

LeetCode-435-无重叠区间

题目链接&#xff1a; 力扣435 -无重叠区间 解题思路&#xff1a;和之前的合并区间、汇总区间都比较相似&#xff0c; 先对二维数组排序&#xff0c;按照左边界升序&#xff1b;当 当前区间的左区间 < 前一个区间的右区间&#xff0c;说明有重叠&#xff0c;res1,还要更新当…

【黑马头条之项目部署_持续集成Jenkins】

本笔记内容为黑马头条项目的项目部署_持续集成部分 目录 一、内容介绍 1、什么是持续集成 2、持续集成的好处 3、今日内容 二、软件开发模式 1、软件开发生命周期 2、软件开发瀑布模型 3、软件的敏捷开发 三、Jenkins安装配置 1、Jenkins介绍 2、Jenkins环境搭建 …