追寻数组的轨迹,解开算法的情愫

在这里插入图片描述

公主请阅

  • 1. 移除元素
    • 1.1 题目说明
      • 示例 1
      • 示例 2
    • 1.2 题目分析
    • 1.3 代码部分
    • 1.4 代码分析
  • 2. 删除有序数组中的重复项
    • 2.1 题目说明
      • 示例 1
      • 示例 3
    • 2.2 题目分析
    • 2.3 代码部分
    • 2.4 代码分析

1. 移除元素

在这里插入图片描述

题目传送门

1.1 题目说明

题目描述
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,元素的顺序可能会发生改变。然后返回数组中与 val 不同元素的个数 k

要求:

  1. 修改数组 nums,使得数组的前 k 个元素包含所有与 val 不同的元素。
  2. 数组剩余元素的顺序和大小无关紧要。

函数应返回:数组中 k 的值,即与 val 不同的元素的个数。

示例

示例 1

  • 输入:nums = [3, 2, 2, 3], val = 3
  • 输出:2, nums = [2, 2, _, _]
  • 解释:数组中的前两个元素为 2,移除元素 3

示例 2

  • 输入:nums = [0, 1, 2, 2, 3, 0, 4, 2], val = 2
  • 输出:5, nums = [0, 1, 4, 0, 3, _, _, _]
  • 解释:数组中的前五个元素为 0, 1, 4, 0, 3,移除了 2

提示

  1. 数组的长度范围为:0 <= nums.length <= 100
  2. 数组元素的值范围:0 <= nums[i] <= 50
  3. 要移除的值 val 的范围:0 <= val <= 100

这道题的核心是双指针技巧,用一个指针遍历整个数组,另一个指针记录有效的(与 val 不同的)元素的位置。

1.2 题目分析

这个题让我们将数组中值等于val的进行删除的操作
那么我们就可以使用快慢指针进行操作了
但是这个并非是真正的指针,对于数组来说这个是下标
这个题其实很简单,我们定义快慢指针,快指针进行遍历数组的操作,如果快指针遍历到的数组的元素大小不等于val的话,那么我们就将当前位置赋值给慢指针的位置上面,然后慢指针进行++移动的操作,然后我们就间接的将这个val的值删除了
好的,让我举个具体的例子来说明这个解法。

如果把 i 变为慢指针,而 j 变为快指针,我们的解法和思路会稍有不同,但逻辑依然可以保持不变。具体来说,i 用来记录当前的有效位置,而 j 用来遍历数组。

修改后的思路:

  • 快指针 j 遍历数组的每个元素。
  • 慢指针 i 用来记录下一个不等于 val 的元素要存放的位置。

当我们发现 nums[j] 不等于 val 时,我们将 nums[j] 放到 nums[i] 的位置,然后将 i 向前移动。

具体实现步骤:

  1. 初始化慢指针 i0,表示下一个不等于 val 的元素要存放的位置。
  2. 遍历数组 nums,使用快指针 j
  3. 如果 nums[j] != val,则将 nums[j] 复制到 nums[i],并将慢指针 i 向前移动一位。
  4. 最后,返回 i,此时它表示的是有效数组的长度。

举个例子:

假设输入:

  • nums = [3, 2, 2, 3]
  • val = 3

初始状态:

  • nums = [3, 2, 2, 3]
  • val = 3
  • 慢指针 i = 0,快指针 j = 0

过程演示:

  1. 第一轮

    • j = 0nums[0] = 3,等于 val,跳过。此时,i 不动。
    • 状态:nums = [3, 2, 2, 3]i = 0j = 1
  2. 第二轮

    • j = 1nums[1] = 2,不等于 val,将 nums[1] 复制到 nums[i],即 nums[0] = 2,然后 i++
    • 状态:nums = [2, 2, 2, 3]i = 1j = 2
  3. 第三轮

    • j = 2nums[2] = 2,不等于 val,将 nums[2] 复制到 nums[i],即 nums[1] = 2,然后 i++
    • 状态:nums = [2, 2, 2, 3]i = 2j = 3
  4. 第四轮

    • j = 3nums[3] = 3,等于 val,跳过,i 不动。
    • 状态:nums = [2, 2, 2, 3]i = 2j = 4,遍历结束。

最终结果

  • i = 2,表示新数组的长度为 2,即 nums 的前 2 个元素为 [2, 2]
  • 数组后面的部分内容无关紧要。

解释:
在整个过程中,快指针 j 负责遍历数组,找到不等于 val 的元素后将其复制到慢指针 i 所在的位置,并将慢指针 i 向前移动一位。最终,i 的值就是数组中不等于 val 的元素个数。

总结:
对于 nums = [3, 2, 2, 3],移除 3 后的有效数组长度为 2,修改后的数组前两个元素为 [2, 2]


1.3 代码部分

//使用双指针
//当快指针指向的值不等于要移除的 val 时,将该值赋给慢指针指向的位置,并移动慢指针
int removeElement(int* nums, int numsSize, int val)
{int i=0;//慢指针for(int j=0;j<numsSize;j++)//快指针遍历整个数组{if(nums[j]!=val){nums[i]=nums[j];//将这个位置的值赋值给慢指针指向的位置i++;//慢指针往后移动}}return i;
}

1.4 代码分析

我们先定义变量i0,用来当做慢指针,然后我们在for循环中定义j来当做快指针,我们在for循环中,我们进行判断,如果当前的j下标的值等于我们要删除的val的话,我们直接将这个跳过,但是如果我们遇到不等于val的值的话,我们就将当前的值赋值到i这个位置上面,然后我们的i进行加加的操作,出了循环之后,我们数组中的val已经被删除完了,因为题目让我们返回与val不同的元素,那么我们怎么操作呢?
我们在for循环里面,我们进行了判断,如果不等于val的话,就让当前的值赋值到i的位置上面,并且我们的i也是会走一步的,那么我们i走了多少步,那么就存在多少个不等于val的元素,那么我们将i进行返回就行了


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

在这里插入图片描述

题目传送门


2.1 题目说明

给你一个 非严格递增排列 的数组 nums,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持一致。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k,你需要做以下事情确保你的题解可以通过:

  • 更改数组 nums,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小无关。
  • 返回 k

判题标准:
系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案int k = removeDuplicates(nums); // 调用assert k == expectedNums.length;
for (int i = 0; i < k; i++) {assert nums[i] == expectedNums[i];
}

如果所有断言都通过,那么您的题解将被 通过

示例 1

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2,并且原数组 nums 的前两个元素被修改为 [1,2]。不需要考虑数组中超出新长度后面的元素。

示例 3

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4,_]
解释:函数应该返回新的长度 5,并且原数组 nums 的前五个元素被修改为 [0,1,2,3,4]。不需要考虑数组中超出新长度后面的元素。

提示:

  • 1 <= nums.length <= 3 * 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums 已按 非严格递增 排列

2.2 题目分析

因为给到我们的数组是有序的,那么这个重复的数字的话肯定是排列在一起的,重复元素是相邻的
我们可以初始化两个指针,i 指向数组的第一个元素,j 从第二个元素开始遍历。如果 nums[j]nums[i] 不相等,说明 nums[j] 是一个新的不同的元素,将其放到 nums[i+1] 的位置上,然后i向前移动一位。那么我们就实现了将重复的第二个元素删除了
然后遍历完数组的话,我们的i+1就是我们新数组的长度了

2.3 代码部分

//只保留每个元素出现的第一个位置的那个元素
//因为这个数组是有序的,所以重复元素肯定是相邻的
//使用一个慢指针 i 来跟踪去重后的数组,并使用一个快指针 j 来遍历数组。
//只要当前元素 nums[j] 不等于 nums[i](即发现了新的元素),就将 nums[j] 放到 i 的下一个位置,并更新 i 的位置。/*
如果数组为空或者只有一个元素,直接返回数组的长度即可。
初始化两个指针,i 指向数组的第一个元素,j 从第二个元素开始遍历。
如果 nums[j] 和 nums[i] 不相等,说明 nums[j] 是一个新的不同的元素,将其放到 nums[i+1] 的位置上,然后 i 向前移动一位。
遍历完数组后,i + 1 就是新数组的长度。*/
int removeDuplicates(int* nums, int numsSize)
{if(numsSize==0)//数组为空,直接返回长度0{return 0;}int i =0;for(int j=1;j<numsSize;j++){if(nums[j]!=nums[i])//发现新元素{i++;//换下一个元素进行寻找nums[i]=nums[j];//将新元素放到重组后的数组中}}//到这里的话就是已经完成了操作重复项了return i+1;//返回去重后的数组的长度
}

2.4 代码分析

我们先对特殊情况进行判断,若果当前的数组是空的话,那么我们直接返回0就行了
然后我呢定义一个指针i,初始化为0,然后再定义一个指针j,初始化为1,我们利用j进行遍历数组
如果当前j指向的数字的和我们的i指向的数字是不一样的话,不那么我们就让i往右走一步,然后我们将当前j指向的数字放到我们的i的位置
举个例子:
一个数组:1 1 2
一开始我们的i指向我们的第一个1,j指向我们的第二个1,然后我们进行循环里面的判断操作,因为当前的j下标的元素等于i的指向的元素,那么我们不进行操作,然后我们的j++j指向我们的2,然后我们的2不等于1,所以我们直接先让i走到第二个i个位置,然后我们将j指向的2赋值到当前i的位置,然后我们的数组就变成这样子了 1 2 2
实际的数据只有两个了
那么我们怎么返回删除重复元素的数组的长度呢?
因为我们的i是0开始的,然后只要遇到不同的元素,我们的i就进行加加的操作,那么我们的数组长度就是i+1,那么我们返回i+1就行了,这个就是我们有效数组的长度了

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

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

相关文章

element-时间选择器单独写两个时间选择器并按照规则进行置灰选择,精确到时分秒

项目场景&#xff1a; 要求&#xff1a; 开始时间和结束时间可以分开搜索&#xff0c;所以组件自带的时间范围选择器不适用开始时间和结束时间超过当前时间置灰不可选择开始时间不可选择结束时间之后的时间结束时间不可选择开始时间之前的时间 代码实例 <el-form-item>&…

软件质量管理体系,软件评审资料,资质认证资料,安全建设,数据安全及项目管理全套资料(原件参考)

软件项目质量管理体系是指一套系统化的管理方法、流程、工具和文档&#xff0c;旨在确保软件项目从需求分析、设计、开发、测试到部署和维护的整个生命周期中&#xff0c;都能达到预定的质量标准和客户期望。该体系通过明确的角色和责任、标准化的工作流程、有效的质量控制和持…

搭建微信AI机器人

AI WeWork Robot是一个基于Python的企业微信机器人&#xff0c;能够接入等大型语言模型。 默认配置为Gemini-Pro&#xff0c;它可以帮助企业自动化处理信息&#xff0c;提供智能回复等功能&#xff0c;经过本人一年测试&#xff0c;稳如老狗 特性 ● 自动回复消息 ● 接入多种…

若依框架定制

1. 若依框架修改器 若依框架修改器是一个可以一键修改RuoYi框架包名、项目名等的工具。 1.1 下载地址 https://gitee.com/lpf_project/RuoYi-MT/releases 1.2 项目修改 选择文件&#xff0c;修改后项目目录如右图所示。 2. 新建业务模块 2.1 新建子业务模块 &#xff08…

vue 项目i18n国际化,快速抽离中文,快速翻译

国际化大家都知道vue-i18n 实现的&#xff0c;但是有个问题&#xff0c;就是繁杂的抽离中文字符的过程&#xff0c;以及翻译中文字符的过程&#xff0c;关于这个有些小工具可以希望可以帮到大家 1.安装vue-i18n npm i vue-i18n8.22.22.ElementUI多语言配置 在src目录下创建…

若依框架的下载与配置

1. 若依版本 RuoYi-Vue前后端分离版。 2. 框架下载 2.1 后端框架下载 https://gitee.com/y_project/RuoYi-Vue 2.2 前端框架下载 https://github.com/yangzongzhuan/RuoYi-Vue3 3. 数据库配置 3.1 创建数据库 基于MySQL数据库&#xff0c;创建数据库&#xff1a;ry-vu…

SpringBoot物流管理系统设计与实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

1971. 寻找图中是否存在路径

有一个具有 n 个顶点的 双向 图&#xff0c;其中每个顶点标记从 0 到 n - 1&#xff08;包含 0 和 n - 1&#xff09;。图中的边用一个二维整数数组 edges 表示&#xff0c;其中 edges[i] [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接&#x…

【贪心算法】刷刷刷刷刷刷题(上)

供自己复习&#xff0c;一篇10题左右 1.分发饼干2.分发糖果3.跳跃游戏I4.跳跃游戏II5.合并区间6.无重叠区间7.划分字母区间8.加油站 1.分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&…

SERDES高速链路PCB设计的信号完整性考虑

链路包括一个发射模块、一个接收模块以及介于两者之间的所有称为“信道”的部分。在网络和电信设备中&#xff0c;信道通常包括线路卡和背板或中板。假设线性接收器处的波形只是发射波形与信道冲激响应的卷积&#xff0c;如果信道频率响应作为频率的函数是均匀的&#xff0c;则…

数据结构修炼——常见的排序算法:插入/希尔/选择/堆排/冒泡/快排/归并/计数

目录 一、常见的排序算法二、常见排序算法的实现2.1 排序算法回顾2.1.1 冒泡排序2.1.2 堆排序 2.2 直接插入排序2.3 希尔排序2.4 选择排序2.5 快速排序2.5.1 快速排序&#xff08;霍尔法&#xff09;2.5.2 快速排序&#xff08;挖坑法&#xff09;2.5.3 快速排序&#xff08;前…

GJB438C-2021《软件需求规格说明》的一处修订

今日偶见GJB438C-2021附录J《软件需求规格说明》的正文格式。 其中3.3.X.d条中的第2&#xff09;和5&#xff09;中使用了术语“数据元素组合体”&#xff1a; 在上一版本GJB438B-2009中的对应文字是&#xff1a; 我觉得把“包”改为“数据元素组合体”是合适的&#xff0c;其…

手机玩使命召唤21:黑色行动6?GameViewer远程玩使命召唤教程

使命召唤21&#xff1a;黑色行动 6这个第一人称射击游戏&#xff0c;将于10月25号上线&#xff01;如果你是使命召唤的老玩家&#xff0c;是不是也在期待这部新作&#xff1f;其实这个游戏不仅可以用电脑玩&#xff0c;还可以用手机玩&#xff0c;使用网易GameViewer远程就能让…

Termius工具在MAC的使用出现的问题:

Termius工具在MAC的使用出现的问题&#xff1a; 在使用SFTP时&#xff0c;出现不了本地的文件的位置 解决方案&#xff1a; 在Apple store下载的使用不了LOCAL SFTP&#xff0c; 需要在网页上进行下载才可以&#xff1a; 官网下载地址&#xff1a;https://termius.com/down…

Redis简介及其在NoSQL应用开发中的优化策略

Redis简介 REDIS数据库为NOSQL的其中一种&#xff0c;又称为REDIS缓存。 80%的系统瓶颈主要出现在数据库一侧 --(海量并发下&#xff0c;网络、磁盘IO开销会导致数据库性能出现瓶颈) --(海量数据下&#xff0c;数据查找可能需要关联上千张表、遍历数千万的数据、花费几分钟) 为…

python-django-mysql原生sql增删改查搭建搭建web项目

先看我本地的项目结构 1 设置虚拟环境 python -m venv venv .\venv\Scripts\activate 2 在虚拟环境中安装Django 执行 pip install -r requirements.txt asgiref3.8.1 backports.zoneinfo0.2.1 Django3.2 mysqlclient2.2.4 pytz2024.2 sqlparse0.5.1 typing-extensions4.1…

利用AI提升论文写作效率:高效提示词指南

利用AI提升论文写作效率&#xff1a;高效提示词指南 前言1. 论文构思与选题2. 文献综述3. 理论框架和方法论4. 数据分析与结果讨论5. 论文撰写与润色6. 参考文献与引用7. 摘要和关键词结语 前言 在这个信息爆炸的时代&#xff0c;学术研究和论文写作已经成为了知识传播和学术发…

微信小程序文字转语音播报案例

插件申请 在小程序官方申请同声传译插件&#xff0c;地址&#xff1a; mp.weixin.qq.com 引入插件 在app.json中加入 "plugins": {"WechatSI": {"version": "0.3.6","provider": "wx069ba97219f66d99"}},封装…

linux介绍与基本指令

前言 本次博客将会讲解linux的来源历史、linux操作系统的理解以及它的一些基本指令。 1.linux的介绍 linux的来源 linux的来源最初还是要说到unix操作系统的。 1968年&#xff0c;一些来自通用电器公司、贝尔实验室和麻省理工学院的研究人员开发了一个名叫Multics的特殊操作…

10.22 MySQL

存储过程 存储函数 存储函数是有返回值的存储过程&#xff0c;存储函数的参数只能是in类型的。具体语法如下&#xff1a; characteristic 特性 练习&#xff1a; 从1到n的累加 ​​​​​​ create function fun1(n int) returns int deterministic begindeclare total i…