力扣面试经典算法150题:移除元素
移除元素
今日的题目依旧是力扣面试经典算法150题中数组相关的题目:移除元素
题目链接:https://leetcode.cn/problems/remove-element/description/?envType=study-plan-v2&envId=top-interview-150
题目描述
给定一个排序数组 nums
和一个值 val
,需要在原地移除数组中所有等于val
的元素,并返回移除后数组的新长度。不需要考虑超出新长度以外的元素。
- 注意:
- 必须在原地修改输入数组,不能使用额外的数组空间。
- 元素的顺序可以改变,你不需要考虑数组中超出新长度后面的元素。
- 示例:
- 输入:
nums
= [3,2,2,3],val
= 3 - 输出:
新长度为 2,数组变为 [2,2](注意:返回值为新长度,数组内容可以不是连续的)
- 输入:
- 解释:
- 数组
nums
中的值 3 被移除了两次。 - 移除后的新数组长度为 2,数组内容为 [2,2]。
- 数组
题目分析
题目要求我们在不使用额外空间的情况下,移除数组中的特定元素,并返回移除后的数组长度。
为了达到 O(1) 的额外空间复杂度,这要求我们需要在原地修改数组。
解题思路
题目的要求就两个,一个移出元素,一个将不同的元素放到原本的数组中。这就意味着我们需要在一个循环中进行两种操作,这里很容易就会想到用双指针来完成,一个指针拿出元素比较,一个指针将元素放入数组,并且这个指针最后停留的下标就是最后一个不同的元素。
实际算法代码
根据以上分析和思路,我们可以写出以下代码:
import java.util.Arrays;/*** description** @author 明月望秋思* @date 2024/8/6 */
public class RemoveElement {/*** 移除数组中的指定元素** @param nums 输入数组* @param val 需要移除的值* @return 移除后的新数组长度*/public int removeElement(int[] nums, int val) {// 指针1,用于遍历数组比较元素int i = 0;// 指针2,用于记录新数组的下标位置int j = 0;// 遍历数组while (i < nums.length) {// 比较元素是否与val相等if (nums[i] != val) {nums[j] = nums[i];// 只有元素不同时,才放入元素并更新指针2j++; }// 更新指针1,不管元素是否相同,都要向下遍历i++; }// 返回新数组的长度,因为在循环中进行了++的操作return j; public static void main(String[] args) {RemoveElement solution = new RemoveElement();// 示例数据int[] nums = {3, 2, 2, 3};int val = 3;// 调用移除方法int newLength = solution.removeElement(nums, val);// 输出新长度和移除后的数组System.out.println("New length: " + newLength);System.out.println("Modified array: " + Arrays.toString(Arrays.copyOfRange(nums, 0, newLength)));}
}
提交代码,测试通过。
因为算法用到了双指针,下面讲一下双指针法的内容。
双指针法
双指针法是一种常用的算法技巧,它通过使用两个指针来遍历数据结构(如数组或链表),以简化问题的解决过程。
使用场景
双指针法适用于多种场景,下面列举了一些常见的使用双指针法的场景及其原因:
- 在原数组对象操作数组
- 场景描述:不增加额外空间复杂度度的情况下完成对数组的操作。
- 原因:双指针法可以直接在原数组上进行操作,可以减少不必要的比较和浪费额外的空间。
- 寻找两个数使它们的和为特定值
- 场景描述:给定一个有序数组,找到数组中两个数,使它们的和等于特定的目标值。
- 原因:有序数组允许我们使用双指针从两端向中间逼近,一个指针从头部开始,另一个从尾部开始。这样可以避免不必要的比较,提高效率。
- 快速排序中的分区操作
- 场景描述:在快速排序算法中,需要选择一个基准值,并将小于基准值的元素放在左边,大于基准值的元素放在右边。
- 原因:双指针可以帮助我们有效地进行分区操作,一个指针从左向右移动,另一个从右向左移动,当两个指针指向的元素不符合分区规则时,交换它们的位置。
- 求解回文子串
- 场景描述:给定一个字符串,判断它是否是回文串,或者找出最长的回文子串。
- 原因:对于回文串,中心对称的特性使得我们可以使用双指针从中心向两边扩展来检查字符串是否为回文。
- 求解链表的中间节点
- 场景描述:给定一个单链表,需要找到链表的中间节点。
- 原因:使用快慢指针,快指针每次移动两步,慢指针每次移动一步,当快指针到达链表尾部时,慢指针正好位于中间。
- 反转链表
- 场景描述:给定一个链表,需要反转链表的顺序。
- 原因:使用双指针技巧,一个指针指向当前节点,另一个指针指向当前节点的前一个节点,通过调整指针方向来实现反转。
- 滑动窗口
- 场景描述:在数组或字符串中找到满足特定条件的最大或最小子序列。
- 原因:双指针可以用来定义滑动窗口的边界,一个指针作为窗口的起始位置,另一个指针作为窗口的结束位置,随着遍历,动态调整窗口大小以满足条件。
- 寻找重复元素
- 场景描述:在有序数组中查找重复元素。
- 原因:使用双指针技巧,一个指针从头开始,另一个指针从尾开始,根据元素的大小关系移动指针来寻找重复项。
- 合并两个有序数组
- 场景描述:给定两个有序数组,需要将它们合并成一个新的有序数组。
- 原因:使用双指针从后向前比较两个数组的元素,并将较大的元素放入结果数组的末尾,可以保证合并后的数组仍然是有序的。
- 检测链表中的环
- 场景描述:给定一个链表,需要检测链表中是否存在环。
- 原因:使用快慢指针技巧,快指针每次移动两步,慢指针每次移动一步,如果存在环,快指针最终会追上慢指针。
双指针法之所以在这些场景中有效,是因为它能够减少不必要的比较次数,提高算法的时间效率,并且在很多情况下能够避免使用额外的空间,从而达到 O(1) 的空间复杂度。
双指针法的优点:
双指针法有以下优点:
- 原地修改:不需要额外的空间来存储新数组,直接在原数组上进行修改,这样就可以在 O(1) 的额外空间复杂度下完成移除操作。
- 保持有序性:在移除元素的过程中,可以使有效元素仍然保持有序。
- 效率高:只需要遍历一次数组即可完成移除操作,时间复杂度为 O(n)。
- 简单易实现:双指针法的逻辑简单,易于理解和实现
总结
实际上上一篇文章中的题目,也是用的双指针法。
双指针法在处理数组的算法题时,是比较常见且又好用的一种解决办法。
熟练使用可以更好的帮助在数组方面的问题!
相关文章:

力扣面试经典算法150题:移除元素
移除元素 今日的题目依旧是力扣面试经典算法150题中数组相关的题目:移除元素 题目链接:https://leetcode.cn/problems/remove-element/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 给定一个排序数组 nums 和一个值 val&a…...
java关于前端传布尔值后端接收一直为false问题
前端传值: {"message":"我肚子疼","isChiefComplaint": true }后端接收对象结构体: public class SymptomInquiryDTO {private String message;private boolean isChiefComplaint; }结果后端接收到的值一直是false&…...

工具学习_CVE Binary Tool
1. 工具概述 CVE Binary Tool 是一个免费的开源工具,可帮助您使用国家漏洞数据库(NVD)常见漏洞和暴露(CVE)列表中的数据以及Redhat、开源漏洞数据库(OSV)、Gitlab咨询数据库(GAD&am…...

智观察 | 行业赛道里的AI大模型
“AI改变世界”被炒得热火朝天,结果就换来AI聊天? 实际上,在日常娱乐之下,AI正在暗暗“憋大招”,深入各行各业,发挥更专业的作用。 自动驾驶 最近“萝卜快跑”霸榜热搜长达一周,让无人驾…...
linux 进程 inode 信息获取
根据端口查找 ss -neltup | grep "$port"根据 pid 查找 ss -neltup | grep "pid$pid"根据 inode 查找 ss -neltup | grep "ino:$inode"根据pid查找进程打开的inode ls -al /proc/$pid/fd查看inode信息 cat /proc/$pid/net/tcp | grep $ino…...

计算机网络-网络层
负责在不同的网络之间转发数据包,基于数据包的 IP地址转发,每个数据包可以按照不同路径传输。网络层不负责丢包重传,以及数据包之间数据顺序的的问题。 网络设备 路由器工作在第三层:网络层,能看到网络层的地址&…...

机器学习:识别AI,GraphRAG,LoRA,线性变换,特征
1.AI识别 1.bitgrit 生成式 AI API 文档 生成式 AI 假图像检测 API 可用于以编程方式检测假图像(即由生成式 AI 创建的图像)。2.X Virality Prediction API 旨在预测推文的潜在病毒式传播力。https://bitgrit.net/api/docs/x_virality_prediction 2.Gr…...

阿里云SMS服务C++ SDK编译及调试关键点记录
一. 阿里云SMS服务开通及准备工作 在阿里云官网上完成这部分的工作 1. 申请资质 个人or企业 我这里是用的企业资质 2. 申请签名 企业资质认证成功后,会自动赠送一个用于测试的短信签名 也可以自己再进行申请,需要等待审核。 3. 申请短信模板 企…...

Flutter 正在迁移到 Swift Package Manager ,未来会弃用 CocoaPods 吗?
什么是 Swift Package Manager ?其实 Swift Package Manager (SwiftPM) 出现已经挺长一段时间了,我记得第一次听说 SwiftPM 的时候,应该还是在 2016 年,那时候 Swift 3 刚发布,不过正式出场应该还是在 2018 年的 Apple…...

PDF——分割pdf的10个工具
PDF分割器是一种可用于将PDF文档分割成更小的文档甚至单个页面的工具。分割 PDF 文档的主要原因是为了更容易共享。 但该过程的成功取决于您用于拆分 PDF 的工具。较简单的工具仅提供几个选项,可能并不适合所有类型的文档。我们将在本文中列出的 10 个最佳 PDF 分割…...
深入解析 Nginx 反向代理:配置、优化与故障排除
深入解析 Nginx 反向代理:配置、优化与故障排除 Nginx 是一个高性能的 HTTP 和反向代理服务器,它以其高并发和高可扩展性在业界享有盛誉。反向代理是 Nginx 的重要功能之一,通过反向代理可以实现负载均衡、安全代理、缓存等多种用途。本篇文…...

深度学习入门(一):感知机与输入数据
单层感知机与多层感知机 单层感知机(Single-Layer Perceptron)和多层感知机(Multi-Layer Perceptron,简称MLP)是神经网络的基本形式,用于执行各种机器学习任务,包括分类和回归。它们都基于早期…...

kubernetes 集群组件介绍
kubernetes 集群组件介绍 Kubernetes 架构 在Kubernetes(k8s)集群中,主节点(Master Node)和工作节点(Worker Node)都运行特定的软件组件,它们共同管理和运行容器化的应用程序。以下…...

Java | Leetcode Java题解之第327题区间和的个数
题目: 题解: class Solution {public int countRangeSum(int[] nums, int lower, int upper) {long sum 0;long[] preSum new long[nums.length 1];for (int i 0; i < nums.length; i) {sum nums[i];preSum[i 1] sum;}BalancedTree treap ne…...
开发一个MutatingWebhook
介绍 Webhook就是一种HTTP回调,用于在某种情况下执行某些动作,Webhook不是K8S独有的,很多场景下都可以进行Webhook,比如在提交完代码后调用一个Webhook自动构建docker镜像 准入 Webhook 是一种用于接收准入请求并对其进行处理的…...

【leetcode详解】另一棵树的子树 (C++递归:思路精析 过程反思)
思路详解: 总体框架: 对root树进行先序遍历,如果当前结点(记为cur)的值和subRoot的根节点值相等时,就开始判断 以cur为根节点的树 和 子树 是否结构一样? 如何判断两棵树是否结构完全相同? …...
物联网遇到人工智能,极快的加速物联网时代
近些年物联网已成为众多科技企业的战略目标,如智能家居等,在未来,手机、传感器等智能设备都走进了生活当中,据数据显示已经有80%以上的的智能手机配备了人工智能。人工智能也不陌生,自动驾驶、人脸识别这些应用场景都是…...

Vue3+Ts项目中经常遇到导入组件,vscode报无法找到模块xxx,xxx隐式拥有 “any“ 类型解决办法~
1、报错截图: 2、解决办法:在确保路径正确的情况下,你会在 src 目录下找到一个名为 env.d.ts 的文件(或者类似的名称)。在这个文件中,你可以声明 .vue 文件的模块类型。例如:(这告诉 TypeScript…...
郑州轻工业大学zzulioj1151~1159合集
郑州轻工业大学zzulioj1151~1159合集 郑州轻工业大学zzulioj1151~1159合集 1150数数多少个整数1151大整数加法题目描述1152: 二分搜索1153简易版最长序列题目描述1154: 校门外的树1155字符串比较 多实例题目描述1156单数变复数题目描述1157连续的n个1题目描述1158又是排序&…...

开发框架DevExpress XAF v24.2产品路线图预览——增强跨平台性
DevExpress XAF是一款强大的现代应用程序框架,允许同时开发ASP.NET和WinForms。XAF采用模块化设计,开发人员可以选择内建模块,也可以自行创建,从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。 DevExpress XAF是一…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...

若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...