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

LeetCode数组-移除元素

简介


数组在内存中是连续存放数据的,如果数组为【1,2,3,4,5】,移除元素3,后面所有的元素都会往前移动一位向前覆盖,变为【1,2,4,5,5】,一些编程语言会将最后一个5不输出,但其实内存空间中这个数组还是有五个元素。

库函数如果能一步解决Leetcode的题目的话,建议不要使用,如果作为一系列代码中的一部分使用,且明白内部逻辑,再使用。

.


27题移除元素

题目的要求:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。

示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

暴力法

两个for循环,外循环遍历数组移除元素,内循环更新数组完成后面元素的覆盖

// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
class Solution {
public:int removeElement(vector<int>& nums, int val) {int size = nums.size();for (int i = 0; i < size; i++) {if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位for (int j = i + 1; j < size; j++) {nums[j - 1] = nums[j];}i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位size--; // 此时数组的大小-1}}return size;}
};

快慢指针双指针法

核心思想移除元素=发现等于val值的数组元素,将后续的元素覆盖到前面

所以是两个操作:发现和覆盖

我们可以定义两个指针,fast和slow

如果我们要覆盖之前的元素,那就是定义一个新数组,我们可以把slow(覆盖)理解为指向新数组的下标,fast和slow都指向同一个数组,fast一直往前探路,发现一个不等于val的数组元素则让slow下标保存下来,如果发现了等于val的数组元素,则slow不动,fast继续++。

这样的话,我们只需要一次循环就可以结束移除元素的操作,其中:

fast的作用是发现要存放在新数组中的元素

slow的作用是指向要存放的元素在新数组中的下标

class Solution {public int removeElement(int[] nums, int val) {//使用双指针//fast为发现不等于val,要存放在新数组中的元素在当前数组的下标//slow为要存放在新数组中的元素下标int slow=0;for(int fast=0;fast<nums.length;fast++){//如果当前fast指向的数组元素不等于VAL,那么就要放在slow下表对应的新数组位置中if(nums[fast]!=val){nums[slow++]=nums[fast];}}//最后slow的下标为最后一个不等于val的新数组元素下标+1,也就是所有存放在新数组中的元素数量return slow;}
}

时间复杂度O(n)

空间复杂度O(1)

26题删除有序数组中的重复项

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

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

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k 。
  • 输入:nums = [0,0,1,1,1,2,2,3,3,4]
    输出:5, nums = [0,1,2,3,4]

双指针法

class Solution {public int removeDuplicates(int[] nums) {//第一项nums[slow]和nums[fast]肯定相等,而且有序数组,这个值也肯定作为新数组的第一项,所以slow和fast直接从1开始就可以int slow=1;for(int fast=1;fast<nums.length;fast++){   if(nums[fast]!=nums[slow-1]){//fast寻找和nums[slow-1]不一样的放到新数组中就可以nums[slow++]=nums[fast];}}return slow;        }
}

题目中这个数组是递增有序的,所以我们只需要让fast从第二个元素开始寻找和num[slow-1]不一样的元素当做新数组元素num[slow]就可以。


283题移动0 

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:

输入: nums = [0]
输出: [0]

双指针法

就拿[0,1,0,3,12]举例,如果我们按照之前移除元素0来做,覆盖完的数组就是[1,3,12,3,12]

所以这题的关键在于在移动非零数字时,要和slow指针所在的元素进行交换,而不是单纯的覆盖。

class Solution {public void moveZeroes(int[] nums) {int slow=0;for(int fast=0;fast<nums.length;fast++){if(nums[fast]!=0){int temp=nums[slow];nums[slow++]=nums[fast];nums[fast]=temp;}}}
}

844题比较含退格的字符串

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

示例 1:

输入:s = "ab#c", t = "ad#c"
输出:true
解释:s 和 t 都会变成 "ac"。

示例 2:

输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 ""。

示例 3:

输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 "c",但 t 仍然是 "b"。

提示:

  • 1 <= s.length, t.length <= 200
  • s 和 t 只含有小写字母以及字符 '#'

字符串知识补充

  • 快慢指针适合对数组操作,将字符串转为字符数组,char[] arr=String.toCharArray();
  • 最终操作完的字符数组转为字符串,new String(arr)
  • 如果slow处于0的下标位置,意思是已经退格到空字符了,没有其他字符,只要处于1或者以上的位置,肯定有字母,所以可以用substring(0,slow)来处理字符数组转化的字符串

快慢指针法

重点在于字符串的操作,以及如果fast指向了退格号,那我们应该将slow的指针回退,如果slow已经是0了,那就保持不变

class Solution {public String dealString(String st){char[] arr=st.toCharArray();int slow=0;for(int fast=0;fast<arr.length;fast++){if(arr[fast]!='#'){arr[slow++]=arr[fast];}else{//如果已经是空字符了,退格后还是空字符if(slow>0){slow--;}}}return new String(arr).substring(0,slow);}public boolean backspaceCompare(String s, String t) {return dealString(s).equals(dealString(t));}
}

http://www.xdnf.cn/news/7950.html

相关文章:

  • 力扣热题——零数组变换 ||
  • C++(26): 标准库 <iterator>
  • 使用亮数据代理IP+Python爬虫批量爬取招聘信息训练面试类AI智能体(实战指南)
  • 百度地图的地铁图API所有城市的城市名和citycode的对照关系列表
  • 城市停车场光伏-储能-充电系统耦合机制与效益分析
  • Babylon.js学习之路《七、用户交互:鼠标点击、拖拽与射线检测》
  • 嵌入式八股,空闲任务
  • OpenFeign
  • 人工智能100问☞第28问:什么是过拟合与欠拟合?
  • PCB设计实践(二十四)PCB设计时如何避免EMI
  • mmaction2——tools文件夹下
  • MySQL 5.7 实战:JSON 字段提取、Base64 解码与引号问题全解析
  • Spring循环依赖
  • 从版本控制到协同开发:深度解析 Git、SVN 及现代工具链
  • 六台升降台完整的限位保护逻辑
  • springboot3.x只需两步快速整合nacos作配置中心
  • NSSCTF [BJDCTF 2020]YDSneedGirlfriend
  • 深度图转换为点云文件脚本
  • 2025-05-21 Python深度学习5——数据读取
  • 深入解析应用程序分层及 BaseDao 的封装策略
  • Electron 后台常驻服务实现(托盘 + 开机自启)
  • 第18天-NumPy + Pandas + Matplotlib多维度直方图
  • HashMap 两数之和java
  • 【最细】自动化测试-解决日志问题,一文贯通...
  • 深入浅出IIC协议 - 从总线原理到FPGA实战开发 --第四篇:I2C工业级优化实践
  • 2024CCPC辽宁省赛 个人补题 ABCEGJL
  • Plant Cell|澳大利亚国立大学研究团队揭示狗尾草应对长期高温的 “生存秘籍”-三重协同机制逆天改命!
  • 46页 @《人工智能生命体 新启点》中國龍 原创连载
  • fatload使用方式
  • 解锁 YOLOv8 新潜能:EfficientViT 主干网络的优化实践与实验数据解读