LeetCode——数组 移除元素(Java)
移除元素
- 简介
- [简单] 27. 移除元素
- [简单] 26. 删除有序数组中的重复项
- [简单] 283. 移动零
- [简单] 844. 比较含退格的字符串
- [简单] 977. 有序数组的平方
简介
记录一下自己刷题的历程以及代码。写题过程中参考了 代码随想录。会附上一些个人的思路,如果有错误,可以在评论区提醒一下。
一旦设计到数组移除元素,就可以首先考虑一下双指针法
解题。快慢指针法
经常可以比较高效的对数组做一遍处理,把需要删除的元素删掉进行压缩。
[简单] 27. 移除元素
原题链接
(注意:这样的方法是一种不保留原先顺序的方法)
方法①:其实也是一种双指针的思路。设置一个下标指向数组最右边,从头开始遍历,一旦遍历到有元素需要移除,就把他往最后放,并将下标左移,右边区域不再参与遍历,记住一旦有元素被置换到后面,需要将当前循环下标做i--
处理,因为你换过来的元素依然可能是一个需要移除的元素。
class Solution {public int removeElement(int[] nums, int val) {int length = nums.length;int right = nums.length - 1; //替换指针for(int i = 0; i < length; i++){if(nums[i] == val){int temp = nums[right];nums[right] = nums[i];nums[i] = temp;right--;length--; //相当于舍弃末尾的部分长度i--; //置换之后当前位置可能还是一个需要置换的元素,继续检查}}return length;}
}
(注意:该方法保留了原数组的顺序)
方法②:快慢指针法,相当于慢指针负责对快指针指向的元素进行复制,而快指针则会跳过那些不需要复制的元素。
class Solution {public int removeElement(int[] nums, int val) {int fastIndex = 0;int slowIndex = 0;int count = 0;while(fastIndex < nums.length && slowIndex < nums.length - count){nums[slowIndex] = nums[fastIndex];if(nums[fastIndex] == val){count++; }else{slowIndex++;}fastIndex++;}return nums.length - count;}
}
[简单] 26. 删除有序数组中的重复项
原题链接
方法①:根据有序数组的条件,对上面的双指针法进行一定的改造,定义一个tag标记目前碰到的数,之后碰到相同的则快指针跳过,碰到不同的则标记新的tag。
class Solution {public int removeDuplicates(int[] nums) { int fastIndex = 1;int slowIndex = 1;int count = 0;int tag = nums[1]; //题目为有序数组while(fastIndex < nums.length && slowIndex < nums.length - count){nums[slowIndex] = nums[fastIndex];if(nums[fastIndex] == tag){count++;}else{tag = nums[fastIndex];slowIndex++;}fastIndex++;}return nums.length - count;}
}
方法②:直接省去标记的问题,因为数组是有序的,慢指针和快指针所指向的元素只有nums[fastIndex] > nums[slowIndex]
以及nums[fastIndex] == nums[slowIndex]
两种情况,相等的时候快指针即可跳过,一旦不相等即可做赋值操作。
public int removeDuplicates(int[] nums) {//题目为有序数组int fastIndex = 0;int slowIndex = 0;while(fastIndex < nums.length){if(nums[fastIndex] > nums[slowIndex]){nums[++slowIndex] = nums[fastIndex];}else{fastIndex++;}}return slowIndex + 1;}
方法①与方法②速度差距:
[简单] 283. 移动零
原题链接
经典的双指针法。因为末尾要保留0,所以使用对换的swap方式来做。但这样时间效率不是最高的,直接覆盖,然后在末尾使用Arrays.fill(nums,count,nums.length,0);
直接填充0能够更高效。
class Solution {public void moveZeroes(int[] nums) {int fastIndex = 0;int slowIndex = 0;while(fastIndex < nums.length){if(nums[fastIndex] != 0){int temp = nums[fastIndex];nums[fastIndex] = nums[slowIndex];nums[slowIndex] = temp;slowIndex++;}fastIndex++;}}
}
[简单] 844. 比较含退格的字符串
原题链接
方法①:也可以用快慢指针法,把两个字符串该删的删了对最后的结果作比较,这里就不重复实现了。
方法②:看到退格操作'#'
就想到使用栈,用两个栈保存s
和t
经过退格操作之后的值,然后再出栈进行比较。
class Solution {public boolean backspaceCompare(String s, String t) {Stack<Character> sStack = new Stack<>();Stack<Character> tStack = new Stack<>();for(int i = 0; i < s.length(); i++){if(s.charAt(i) == '#' && !sStack.empty()){sStack.pop();}else if(s.charAt(i) != '#'){sStack.push(s.charAt(i));}//System.out.println(sStack.toString());}for(int i = 0; i < t.length(); i++){if(t.charAt(i) == '#' && !tStack.empty()){tStack.pop();}else if(t.charAt(i) != '#'){tStack.push(t.charAt(i));}//System.out.println(tStack.toString());}if(sStack.size() != tStack.size()) return false;while(!sStack.empty() && !tStack.empty()){if(sStack.pop() != tStack.pop()) return false;}return true;}
}
方法③:两个指针从后往前遍历,效率高,但是对边界的控制比较麻烦,没有栈写起来简单
class Solution {public boolean backspaceCompare(String s, String t) {int sIndex = s.length() - 1;int tIndex = t.length() - 1;int sCount = 0;int tCount = 0;while(sIndex >= 0 || tIndex >= 0){//让sIndex指向s中接下来要比较的字符(能够确定最后不被删除while (sIndex >= 0){if (s.charAt(sIndex) == '#') {sCount++;sIndex--;} else if (sCount > 0) {sCount--;sIndex--;} else{break;}}while (tIndex >= 0){if (t.charAt(tIndex) == '#') {tCount++;tIndex--;} else if (tCount > 0) {tCount--;tIndex--;} else{break;}}if(sIndex < 0 || tIndex < 0) break;if (s.charAt(sIndex) != t.charAt(tIndex)){return false;}sIndex--;tIndex--;}if(sIndex >=0 || tIndex >= 0) return false;return true;}
}
[简单] 977. 有序数组的平方
原题链接
题目中没有强调在原数组上修改,返回值也是int[]
,就可以思考是不是创建一个新的数组更方便一些。
找到数组中正负值的分界点,然后从分界点向两边遍历,按照绝对值的大小挨个平方计算后加入到新的数组中。正数或者负数用完之后无法继续进行绝对值比较的循环。然后再将左边或者右边剩下的数依次放入答案数组中。
时间复杂度O(n)
class Solution {public int[] sortedSquares(int[] nums) {int[] answer = new int[nums.length];int zeroIndex = 0;//找到正负分界点while(zeroIndex < nums.length && nums[zeroIndex] < 0){zeroIndex++;}int negativeIndex = zeroIndex - 1;int positiveIndex = zeroIndex;int i = 0;while(negativeIndex >= 0 && positiveIndex < nums.length){if (Math.abs(nums[negativeIndex]) < Math.abs(nums[positiveIndex])) {answer[i++] = nums[negativeIndex] * nums[negativeIndex];negativeIndex--;continue;} else {answer[i++] = nums[positiveIndex] * nums[positiveIndex];positiveIndex++;continue;}}while(negativeIndex >= 0){answer[i++] = nums[negativeIndex] * nums[negativeIndex];negativeIndex--;}while(positiveIndex < nums.length){answer[i++] = nums[positiveIndex] * nums[positiveIndex];positiveIndex++;}return answer;}
}
相关文章:

LeetCode——数组 移除元素(Java)
移除元素 简介[简单] 27. 移除元素[简单] 26. 删除有序数组中的重复项[简单] 283. 移动零[简单] 844. 比较含退格的字符串[简单] 977. 有序数组的平方 简介 记录一下自己刷题的历程以及代码。写题过程中参考了 代码随想录。会附上一些个人的思路,如果有错误&#x…...

enum和Collection.stream()你这样用过么
最近在做一个数据图表展示的功能,显示订单近七天或者近半月的数量和金额。可以理解成下图所示的样子: 我是用枚举和集合的stream方法实现的数据初始化和组装,枚举用来动态初始化时间范围,集合的stream方法来将初始化的数据转换成…...

unittest与pytest的区别
Unittest vs Pytest 主要从用例编写规则、用例的前置和后置、参数化、断言、用例执行、失败重运行和报告这几个方面比较unittest和pytest的区别: 用例编写规则 用例前置与后置条件 断言 测试报告 失败重跑机制 参数化 用例分类执行 如果不好看,可以看下面表格&…...

YOLOv7优化策略:IOU系列篇 | 引入MPDIoU,WIoU,SIoU,EIoU,α-IoU等创新
💡💡💡本文独家改进:MPDIoU,WIoU,SIoU,EIoU,α-IoU等二次创新,总有一种适合你的数据集 MPDIoU,WIoU,SIoU,EIoU,α-IoU | 亲测在多个数据集能够实现大幅涨点 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨✨✨前沿最新计算机顶会复现 …...

SQL Server2000mdf升级SQL Server2005数据库还原
SQL Server2000数据库还原sqlserver 2000mdf升级 sqlserver 2008数据库还原SQL Server2005数据库脚本 sqlserver数据库低版本升级成高版本 sqlserver数据库版本升级 数据库版本还原 如果本机安装了sqlserver2012或者sqlserver2019等高版本 怎么样才能运行sqlserver2000的数据库…...

webSocket推送太快导致前端渲染卡顿问题优化
优化思路: 把webSocket接收到的数据用一个数组存起来,达到一定长度再统一渲染,可根据推送数据的速度适当调解数组长度限制,如果一段时间内改数组长度打不要渲染条件,就用定时器之间渲染 data() {return {tempDataWsLi…...

(Java)泛型总结
泛型类 public class Student<E> {private E a;public Student(E a){this.aa;}public void show(){System.out.println(a);} } 泛型方法 public <E> void show(E a){System.out.println(a);} 泛型接口 public interface Inter <T>{void show(T a); } 类…...

C++ Package继承层次,采用继承实现快递包裹的分类计价(分为空运2日达、陆运3日达)。
一、问题描述: Package继承层次,采用继承实现快递包裹的分类计价(分为空运2日达、陆运3日达)。自定义一个或多个快递公司,自定义计价方法,设计合适、合理的界面文本提示,以广东省内某市为起点&…...

中文大语言模型汇总
推荐一篇非常棒的github:Awesome-Chinese-LLM 另附语言模型排行榜:FastChat 里面总结了几乎所有目前主流的中文大语言模型。在此记录一下,方便以后慢慢学习。...

GEE:GEE中实现简单计算器
作者:CSDN _养乐多_ 本文记录了在 Google Earth Engine(GEE)上实现简单计算器的代码。 APP链接:https://949384116.users.earthengine.app/view/simplecalculator 文章目录 一、完整代码二、代码链接 一、完整代码 // 定义初始…...

概念解析 | 神经网络中的位置编码(Positional Encoding)
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:Positional Encoding 神经网络中的位置编码(Positional Encoding) A Gentle Introduction to Positional Encoding in Transformer Models, Part 1 1.背景介绍 在自然语言处理任…...

【ubuntu】搭建lamp架构
一、准备工作 1、更新源 apt-get updateapt #就是一个管理包的工具,理解为centos中的yum update #表示让apt执行更新的操作,更新的内容为软件列表。#为什么要更新软件列表? 就时本地会隔断时间进行同步镜像站的资源包,但是我…...

GNU ld(链接器)的主要功能
作用: 链接器linker是Bintutils的一种重要工具,负责将编译后的目标文件(.o)合并成一个可执行文件或者共享库。 一、链接器的文件结构可以概括为以下几个关键部分: 输入文件 (Input Files): 输入文件通常是目标文件(.o 文件&#…...

springboot整合FTP实现文件传输
实现ftp文件传输的步骤: 1.ftp绑定ip端口登录 2.切换到指定地址 3.文件下载 4.关闭ftp连接 项目中使用的jar包 <!-- ftp包--><dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><vers…...

Spring Boot 2.x.x 升级至 Spring Boot 3.x.x
小伙伴们,你们好呀,好久不见,我是老寇,跟我一起升级Spring Boot版本 一、JDK 版本 JDK8 需要升级至 JDK17 二、Spring Boot 版本 Spring Boot 2.x.x 升级至 Spring Boot 3.x.x 三、Java Api 变更 javax 变更成 jakarta 四、…...

光电直读水表支持短时间多次抄表吗
传统的水表读数方式已经逐渐无法满足人们对于便捷、准确的需求。为此,光电直读水表应运而生,它凭借出色的读数性能和稳定的准确性,赢得了广大用户的一致好评。那么,光电直读水表支持短时间多次抄表吗?答案是肯定的&…...

家庭私人影院 - Windows搭建Emby媒体库服务器并远程访问 「无公网IP」
文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中,观看视频绝对是主力应用场景之一&…...

核心舱在轨飞行VR沉浸式互动体验满足大家宇宙探险的心愿
近日神州十七号载人飞船迎来发射,随着我国载人航天工程进入空间站应用与发展阶段,在轨航天探索和运维工作进入常态化阶段,然而每次出征都牵动着亿万人民的心,对航天航空的好奇和向往也越来越强烈。为了让普通人也能体验乘坐飞船上…...

k8s集群中namespace状态一直显示Terminating
一、问题现象 今天在做测试时,在一个namespace下无法启动pod,查看ns状态一直显示Terminating [rootnode1 ~]# kubectl get ns NAME STATUS AGE configmap Terminating 135d default Active …...

数据库高速缓存配置
数据库一般都配置数据高速缓存,并且可以高速缓存中按页大小分不同的缓冲池。 Oracle: db_cache_size是指db_block_size对应的缓冲池,也可以指定非db_block_size的缓冲池,一般也都会再配置一个32K的缓冲池,两个缓冲池加…...

性能优化之懒加载 - 基于观察者模式和单例模式的实现
一、引入 在前端性能优化中,关于图片/视频等内容的懒加载一直都是优化利器。当用户看到对应的视图模块时,才去请求加载对应的图像。 原理也很简单,通过浏览器提供的 IntersectionObserver - Web API 接口参考 | MDN (mozilla.org),…...

【LeetCode刷题-链表】--1290.二进制链表转整数
1290.二进制链表转整数 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }*…...

搭建Radius认证服务器 安当加密
搭建Radius认证服务器需要完成以下步骤: 安装Radius服务器软件。可以选择使用FreeRadius、Radiusd或WinRadius等开源软件,也可以选择使用商业软件如Cisco或安当ASP等。配置认证数据库。在Radius服务器上配置认证数据库,用于存储用户信息和认…...

Windows11恢复组策略编辑器功能的方法
原因分析 日常工作学习中,对 Windows 计算机上的问题进行故障排除时,有些高级用户经常使用组策略编辑器轻松修复它。通过其分层结构,您可以快速调整应用于用户或计算机的设置。如果搜索结果中缺少组策略编辑器,则可能必须使用注册表编辑器作为疑难解答工具,这是一种更复杂…...

Django实战项目-学习任务系统-查询列表分页显示
接着上期代码框架,6个主要功能基本实现,剩下的就是细节点的完善优化了。 接着优化查询列表分页显示功能,有很多菜单功能都有查询列表显示页面情况,如果数据量多,不分页显示的话,页面展示效果就不太好。 本…...

Git 拉取指定TAG/分支的代码
像其他版本控制系统(VCS)一样,Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)。 1.创建 tag 标签 $ git tag <tagname&…...

2-爬虫-代理池搭建、代理池使用(搭建django后端测试)、爬取某视频网站、爬取某视频网站、bs4介绍和遍历文档树
1 代理池搭建 2 代理池使用 2.1 搭建django后端测试 3 爬取某视频网站 4爬取某视频网站 5 bs4介绍和遍历文档树 1 代理池搭建 # ip代理-每个设备都会有自己的IP地址-电脑有ip地址---》访问一个网站---》访问太频繁---》封ip-收费:靠谱稳定--提供api-免费ÿ…...

动手学深度学习——残差网络ResNet(原理解释+代码详解)
残差网络ResNet 1. 函数类2. 残差块3. ResNet模型4. 训练模型 ResNet为了解决“新添加的层如何提升神经网络的性能”,它在2015年的ImageNet图像识别挑战赛夺魁 它深刻影响了后来的深度神经网络的设计,ResNet的被引用量更是达到了19万。 1. 函数类 假…...

MYSQL 8.0 配置CDC(binlog)
CDC(Change Data Capture)即数据变更抓取,通过源端数据源开启CDC,ROMA Connect 可实现数据源的实时数据同步以及物理表的物理删除同步。这里介绍通过开启Binlog模式CDC功能。 注意:1、使用MYSQL8.0及以上版本。 2、不…...

软件测试/测试开发丨ChatGPT能否成为PPT最佳伴侣
点此获取更多相关资料 简介 PPT 已经渗透到我们的日常工作中,无论是工作汇报、商务报告、学术演讲、培训材料都常常要求编写一个正式的 PPT,协助完成一次汇报或一次演讲。PPT相比于传统文本的就是有布局、图片、动画效果等,可以给到观众更好…...