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

顺序表算法题 —— 移除元素、删除有序数组中的重复项、合并两个有序数组

目录

一、顺序表算法题

1、移除元素

2、删除有序数组中的重复项 

3、 合并两个有序数组

二、顺序表问题与思考


一、顺序表算法题

1、移除元素

移除元素 - 力扣(LeetCode)

思路分析:

思路一:创建一个新数组,开辟新空间,把符合条件的元素放到新数组中,再释放和销毁旧空间。

思路二:用顺序表査找指定元素,并返回该指定元素的下标,再删除指定下标的位置。

思路三:用一个顺序表查找指定元素,逐个查找指定元素,与符合条件的元素删除,后面往前挪动一个位置。

我们现在以思路三来详细分析一下:

第一层循环:遍历数组,查找val。

第二层循环:val之后的数据整体往前挪动一位。

时间复杂度为O(n^2),对于需要查找多次的复杂算法题比较不友好,运行时间长;

但对于这一道带提示条件的简单算法题,就没有时间限制的要求,所以就无需关心时间复杂度。

但对于追求更高要求的时间和空间的相关算法复杂度的精度,我们从以下思路来入手:

最终思路:

该思路的时间复杂度为O(n);空间复杂度为O(1)。

定义两个变量指向数组第一个位置,判断nums[src]是否等于val,所以有以下两者情况:

(1)当nums[src]等于val,所以src++;

(2)当nums[src]不等于val,所以nums[dst]=nums[src],src++,dst++。

我们就这个数组例子来分析一下:

(1)因为nums[src]等于val,所以src++;当src++后,nums[src]为数组第二个元素的位置,nums[src]不等于val,nums[dst]=nums[src],此时数组第一个元素被赋值为2,再src++,dst++。

(2) 当src++和dst++后,nums[src]为数组第三个元素的位置,nums[sdst]为数组第二个元素的位置。nums[src]不等于val,nums[dst]=nums[src],此时数组第二个元素被赋值为2,再src++,dst++。

(3) 当src++和dst++后,nums[src]为数组第三个元素的位置,nums[dst]为数组第二个元素的位置。此时nums[src]等于val,所以src++。

(4) 此时nums[src]在后面数组外,超出数组的范围,即可为不满足src小于numsSize的条件,跳出循环,返回dst值。

运行代码: 

int removeElement(int* nums, int numsSize, int val) 
{int src = 0;int dst = 0;while(src < numsSize){if(nums[src] == val){src++;}else{nums[dst++] = nums[src++];//dst++;//src++;}}//此时dst指向的位置就是要返回的有效个数return dst;
}

运行提交结果:

 

2、删除有序数组中的重复项 

删除有序数组中的重复项 - 力扣(LeetCode) 

 

思路分析:

思路一:指针指向第一个元素,然后与它后面的元素进行比较,若相等,第一个元素和它后面的一个元素以外的整体前移;若不相等,则指针后移一位,以此类推。

思路二:定义两个变量,dst为第一个位置,src为第一个位置的下一个位置,判断src和dst位置的数据,因此有以下两者情况:

(1)若相等,src++;

(2)若不相等,dst++,nums[dst]=nums[src],src++。

思路二只有一层循环,时间复杂度为O(n);空间复杂度为O(1)

我们以思路二的一个例子来入手分析一下:

(1)此时nums[dst]==nums[src],所以src++,此时src为第三个元素的位置。

(2)此时nums[dst] != nums[src],则dst++,此时dst为第二个元素的位置,所以使nums[dst]=nums[src],再让src++。

(3)此时nums[src]在后面数组外,超出数组的范围,即可为不满足src小于numsSize的条件,跳出循环,返回dst值。

总结规律:

        两个重复的元素必定相邻,不可能中间有间隔的元素,所以直接相当于把重复的元素删掉,只保留不重复的元素,保持有序性。

运行代码: 

int removeDuplicates(int* nums, int numsSize) 
{int dst = 0, src = dst+1;while(src < numsSize){//nums[dst]  nums[src]//相同(重复) src++//不相同,dst++,赋值,src++if(nums[dst] != nums[src] && ++dst != src){nums[dst] = nums[src];}src++;}return dst+1;
}

运行提交结果:

 

3、 合并两个有序数组

合并两个有序数组 - 力扣(LeetCode)

思路分析:

        根据题目要求,我们可以创建三个指针,分别指向num1最后一个有效数据位置,num2最后一个数据位置,和num1最后一个位置,比较了l1和l2位置的数据,谁大,谁就往l3位置放数据,同时往l3放数据的这个指针和l3这个指针往前移动一个位置,另一个指针不动,继续以上操作。

结束条件:以两种情况为主

(1)l1<0:要处理nums2中数据,循环放到num1中。

(2)l2<0:不需要处理,因为nums2中的数据已经有序的放到num1中了。

我们以该思路分析以下例子:

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

(1)l1和l2的数据相比较,l1的数据大,放到l3的位置处。

(2)同时l1和l3往前移动一个位置 ,l2不动。

 (3)以此类推,重复以上操作,直到l1或l2其中之一指向数组之外。

情况一:

        此例子是l2指向数组之外,即l2<0,此时表明不需要处理,因为nums2中的数据已经有序的放到num1中了。

情况二:

        我们以另一种情况来看,即l1<0,要处理nums2中数据,循环放到num1中,同时往l3放数据的这个指针和l3这个指针往前移动一个位置,另一个指针不动。

该思路只有并列的两层循环,时间复杂度为O(n)或O(m);空间复杂度为O(1)

运行代码:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{int l1 = m - 1;int l2 = n -1;int l3 = m + n - 1;//l1 >= 0  l2 >= 0while(l1 >= 0 && l2 >= 0){if(nums1[l1] > nums2[l2]){nums1[l3--] = nums1[l1--];}else{//l1 == l2 要么 l2 > l1nums1[l3--] = nums2[l2--];}}//跳出while有两种情况:要么l1 < 0(需要处理),要么l2 < 0(不需要处理)while(l2 >= 0){nums1[l3--] = nums2[l2--];}       
}

运行提交结果:

 

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

        为了利用数组 nums 1与 nums 2已经被排序的性质,我们可以使用双指针方法。这一方法将两个数组看作队列,每次从两个数组头部取出比较小的数字放到结果中。

初始两数组状态如下:

排序后的效果:

 

运行代码:

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];}
}

复杂度分析:

  1. 时间复杂度:O(m+n)。指针移动单调递增,最多移动 m+n 次,因此时间复杂度为 O(m+n)。
  2. 空间复杂度:O(m+n)。需要建立长度为 m+n 的中间数组 sorted。

二、顺序表问题与思考

  1. 中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容⼀般是呈2倍的增长,势必会有⼀定的空间浪费。例如当前容量为100,满了以后增容到200, 我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
思考:如何解决以上问题呢?这就需要引入链表的相关内容了,请听下回博客详细分解。

相关文章:

顺序表算法题 —— 移除元素、删除有序数组中的重复项、合并两个有序数组

目录 一、顺序表算法题 1、移除元素 2、删除有序数组中的重复项 3、 合并两个有序数组 二、顺序表问题与思考 一、顺序表算法题 1、移除元素 移除元素 - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 思路一&#xff1a;创建一个新数组&#xff0c;开辟…...

配置ssh后又报错git@github.com: Permission denied (publickey)

再添加一次ssh有用 ssh-add ~/.ssh/你的id_rsa的名字可以先运行 eval "$(ssh-agent -s)"再添加&#xff0c;Jesus每次重启terminal都要输入一遍 报错 gitgithub.com: Permission denied (publickey) 通常是由于 SSH 公钥没有正确配置或者 GitHub 上未能识别你的公钥…...

yolov10安装体验

按照官网 conda create -n yolov10 python=3.9 conda activate yolov10 pip install -r requirements.txt pip install -e . 一路安装,运行yolov10的问题,初次接触的同学可以注意。 Set arbitrary_types_allowed=True in the model_config to ignore this error f you got th…...

使用Docker-Compose部署SpringBoot项目的案例

Docker-Compose是Docker官方的一个开源项目&#xff0c;主要用于实现对Docker容器集群的快速编排和管理。该项目由Python编写&#xff0c;通过调用Docker服务提供的API来管理容器。只要所操作的平台支持Docker API&#xff0c;就可以利用Docker-Compose进行编排管理。Docker-Co…...

大话 RCU (read copy update)

还得是看官方文档。kernel/Document/RCU/WhatisRCU.rst. 首先&#xff0c;我们要搞清楚一件事&#xff0c;指针它是一个变量&#xff0c;他在内存上也是占了空间的&#xff0c;然后他里面的值&#xff0c;是你申请的内存块的首地址。文档开篇就讲咱们的基本原理&#xff0c;就…...

vue项目npm run serve 报错,Error: read ECONNRESET at TCP.onStreamRead

背景&#xff1a;vue2的项目&#xff0c;之前npm run serve一直可以正常使用&#xff0c;突然每次启动都会报错了&#xff0c;报错信息如下&#xff1a; node:events:492 throw er; // Unhandled error event ^ Error: read ECONNRESET at TCP.onStreamRead (n…...

十二、MySQL数据类型精讲

文章目录 1. MySQL中的数据类型2. 整数类型2.1 类型介绍2.2 可选属性2.2.1 M2.2.2 UNSIGNED2.2.3 ZEROFILL 2.3 适用场景2.4 如何选择&#xff1f; 3. 浮点类型3.1 类型介绍3.2 数据精度说明3.3 精度误差说明 4. 定点数类型4.1 类型介绍4.2 开发中经验 5. 位类型&#xff1a;BI…...

不同参数对分类精度的影响以及思考

1 问题 探索不同的batch_size对分类精度的影响探索不同的损失函数对分类精度的影响 2 方法 问题一 要知道的是Batch_size的作用&#xff1a;决定了下降的方向。在合理范围内&#xff0c;增大Batch_size的好处&#xff1a; 一是提高了内存利用率以及大矩阵乘法的并行化效率&…...

开源AI智能名片小程序源码:私域电商构建独特竞争力的新机遇

摘要&#xff1a;本文旨在探讨私域电商如何利用开源AI智能名片小程序源码构建独特竞争力。在强调独特性是通向成功的必要条件的基础上&#xff0c;分析开源AI智能名片小程序源码在私域电商发展独特性方面的作用及相关策略。 一、引言 在竞争激烈的商业环境中&#xff0c;让自己…...

从Web2到Web3:探索下一代互联网的无限可能性

互联网经历了从Web1到Web2的重大变革&#xff0c;现在正迈向Web3。Web2通过社交媒体、电子商务和内容平台改变了我们的数字生活&#xff0c;但同时也伴随着中心化平台的垄断和用户数据被广泛控制的问题。而Web3的出现&#xff0c;则试图通过去中心化技术解决这些挑战&#xff0…...

POE供电支持画中画的摄像头解决方案

首先他的主芯片由嵌入式操作系统和高性能硬件处理平台&#xff0c;具有较高稳定性和可靠性&#xff0c;有丰富的接口&#xff0c;可以支持二次开发定制的. 首先&#xff0c;什么是poe供电呢&#xff1f;Poe供电是通过网络线&#xff08;网线&#xff09;供电的一种技术&#x…...

Python 3 字典

Python 3 字典 引言 Python 字典(Dictionary)是一种非常有用的内置数据类型,用于存储键值对。在 Python 3 中,字典保持了一些基本特性,同时也有一些新的改进和特性。本文将详细介绍 Python 3 中的字典,包括其基本操作、常用方法以及一些高级特性。 字典的基本操作 创…...

CFR( Java 反编译器)

一、安装教程 CFR&#xff08;Class File Reader&#xff09;是一个流行的Java反编译器&#xff0c;它可以将编译后的.class文件或整个.jar文件转换回Java源代码。以下是CFR的下载和使用教程&#xff1a; 下载CFR 访问CFR的官方网站或GitHub仓库&#xff1a;CFR的最新版本和所…...

单片机的两种看门狗原理解析——IWDG和WWDG

一、IWDG独立开门狗的主要性能 计时机制&#xff1a; 递减计数器 独立开门狗的初始频率&#xff1a; LSI低速内部时钟&#xff1a;RC震荡器&#xff0c;40kHz 独立开门狗是以LSI为初始频率的&#xff0c;所以独立开门狗的初始时钟频率取决与单片机本身&#xff0c;因此在使…...

SQL进阶技巧:如何获取状态一致的分组? | 最大、最小值法

目录 0 需求描述 1 数据准备 2 问题分析 方法1&#xff1a;最大、最小值法&#xff08;技巧&#xff09; 方法2&#xff1a;常规思路 3 小结 如果觉得本文对你有帮助&#xff0c;那么不妨也可以选择去看看我的博客专栏 &#xff0c;部分内容如下&#xff1a; 数字化建设通…...

windows10使用bat脚本安装前后端环境之msyql5.7安装配置并重置用户密码

首先需要搞清楚msyql在本地是怎么安装配置、然后在根据如下步骤编写bat脚本&#xff1a; 思路 1.下载mysql5.7 zip格式安装包 2.新增data文件夹与my.ini配置文件 3.初始化数据库 4.安装mysql windows服务 5.启动并修改root密码&#xff08;新增用户初始化授予权限&#xff09…...

文件上传、amrkdown编辑器

一、文件上传 这里我以图片为例&#xff0c;进行上传&#xff0c;上传到阿里云oss&#xff08;对象存在中&#xff09; 首先&#xff0c;我们先梳理一下&#xff0c;图片上传的流程 1、前端选择文件&#xff0c;提交文件 前端提交文件&#xff0c;我们可以使用ElementUI中的…...

Linux防火墙-4表5链

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们经过上小章节讲了Linux的部分进阶命令&#xff0c;我们接下来一章节来讲讲Linux防火墙。由于目前以云服务器为主&#x…...

(最新已验证)stm32 + 新版 onenet +dht11+esp8266/01s + mqtt物联网上报温湿度和控制单片机(保姆级教程)

物联网实践教程&#xff1a;微信小程序结合OneNET平台MQTT实现STM32单片机远程智能控制 远程上报和接收数据——汇总 前言 之前在学校获得了一个新玩意&#xff1a;ESP-01sWIFI模块&#xff0c;去搜了一下这个小东西很有玩点&#xff0c;远程控制LED啥的&#xff0c;然后我就想…...

无环SLAM系统集成后端回环检测模块(loop):SC-A-LOAM以及FAST_LIO_SLAM

最近在研究SLAM目标检测相关知识&#xff0c;看到一篇论文&#xff0c;集成了SC-A-LOAM作为后端回环检测模块&#xff0c;在学习了论文相关内容后决定看一下代码知识&#xff0c;随后将其移植&#xff0c;学习过程中发现我找的论文已经集成了回环检测模块&#xff0c;但是我的另…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...