LeetCode_27_简单_移除元素

文章目录

  • 1. 题目
  • 2. 思路及代码实现(Java)
    • 2.1 双指针
    • 2.2 双指针优化


1. 题目

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

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

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

示例 1:

输入: n u m s = [ 3 , 2 , 2 , 3 ] , v a l = 3 nums = [3,2,2,3], val = 3 nums=[3,2,2,3],val=3
输出: 2 , n u m s = [ 2 , 2 ] 2, nums = [2,2] 2,nums=[2,2]
解释:函数应该返回新的长度 2, 并且 n u m s nums nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 n u m s = [ 2 , 2 , 3 , 3 ] nums = [2,2,3,3] nums=[2,2,3,3] n u m s = [ 2 , 2 , 0 , 0 ] nums = [2,2,0,0] nums=[2,2,0,0],也会被视作正确答案。

示例 2:

输入: n u m s = [ 0 , 1 , 2 , 2 , 3 , 0 , 4 , 2 ] , v a l = 2 nums = [0,1,2,2,3,0,4,2], val = 2 nums=[0,1,2,2,3,0,4,2],val=2
输出: 5 , n u m s = [ 0 , 1 , 3 , 0 , 4 ] 5, nums = [0,1,3,0,4] 5,nums=[0,1,3,0,4]
解释:函数应该返回新的长度 5, 并且 n u m s nums nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。


提示

  • 0 < = n u m s . l e n g t h < = 100 0 <= nums.length <= 100 0<=nums.length<=100
  • 0 < = n u m s [ i ] < = 50 0 <= nums[i] <= 50 0<=nums[i]<=50
  • 0 < = v a l < = 100 0 <= val <= 100 0<=val<=100

2. 思路及代码实现(Java)

2.1 双指针

由于题目要求删除数组中等于 val \textit{val} val 的元素,因此输出数组的长度一定小于等于输入数组的长度,我们可以把输出的数组直接写在输入数组上。可以使用双指针:右指针 right \textit{right} right 指向当前将要处理的元素,左指针 left \textit{left} left 指向下一个将要赋值的位置。

  • 如果右指针指向的元素不等于 val \textit{val} val,它一定是输出数组的一个元素,我们就将右指针指向的元素复制到左指针位置,然后将左右指针同时右移;

  • 如果右指针指向的元素等于 val \textit{val} val,它不能在输出数组里,此时左指针不动,右指针右移一位。

整个过程保持不变的性质是:区间 [ 0 , left ) [0,\textit{left}) [0,left) 中的元素都不等于 val \textit{val} val。当左右指针遍历完输入数组以后, left \textit{left} left 的值就是输出数组的长度。

这样的算法在最坏情况下(输入数组中没有元素等于 val \textit{val} val),左右指针各遍历了数组一次。算法渐进时间复杂度与序列长度 n n n 相关,为 O ( n ) O(n) O(n),而时间复杂度为 O ( 1 ) O(1) O(1),仅保留了原数组的固定空间大小。

class Solution {public int removeElement(int[] nums, int val) {int n = nums.length;int left = 0;for (int right = 0; right < n; right++) {if (nums[right] != val) {nums[left] = nums[right];left++;}}return left;}
}

执行用时:0 ms
消耗内存:40.91 MB

2.2 双指针优化

如果要移除的元素恰好在数组的开头,例如序列 [ 1 , 2 , 3 , 4 , 5 ] [1,2,3,4,5] [1,2,3,4,5],当 val \textit{val} val 为 1 时,我们需要把每一个元素都左移一位。注意到题目中说:「元素的顺序可以改变」。实际上我们可以直接将最后一个元素 5 移动到序列开头,取代元素 1,得到序列 [ 5 , 2 , 3 , 4 ] [5,2,3,4] [5,2,3,4],同样满足题目要求。这个优化在序列中 val \textit{val} val 元素的数量较少时非常有效。

实现方面,我们依然使用双指针,两个指针初始时分别位于数组的首尾,向中间移动遍历该序列。如果左指针 left \textit{left} left 指向的元素等于 val \textit{val} val,此时将右指针 right \textit{right} right 指向的元素复制到左指针 left \textit{left} left 的位置,然后右指针 right \textit{right} right 左移一位。如果赋值过来的元素恰好也等于 val \textit{val} val,可以继续把右指针 right \textit{right} right 指向的元素的值赋值过来(左指针 left \textit{left} left 指向的等于 val \textit{val} val 的元素的位置继续被覆盖),直到左指针指向的元素的值不等于 val \textit{val} val 为止。

当左指针 left \textit{left} left 和右指针 right \textit{right} right 重合的时候,左右指针遍历完数组中所有的元素。

其实这个方法与第一个方法的区别在于,在不开新的存储空间前提下,用数组的末尾部分,存储等于 v a l val val 的值,因为能肯定的是,等于 v a l val val 的值的数量不会大于数组长度 n n n,因此在最坏情况下,该方法两个指针总的移动次数之和为 n n n,节省了左指针在遍历时,重复对需保留元素的赋值操作。因此用大 O O O 法表示的时间复杂度和空间复杂度与上述相同。

class Solution {public int removeElement(int[] nums, int val) {int left = 0;int right = nums.length;while (left < right) {if (nums[left] == val) {nums[left] = nums[right - 1];right--;} else {left++;}}return left;}
}

执行用时:0 ms
消耗内存:40.93 MB

题解来源:力扣官方题解

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

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

相关文章

docker harbor.v2.9.2搭建镜像无法下载问题解决

在通过部署docker harbor时&#xff0c;采用的是离线包的方式&#xff0c;当解压压缩包后&#xff0c;执行prepare脚本步骤中有一步是要获取prepare:v2.9.2版本镜像 结果执行脚本时报如下错误&#xff1a; Unable to find image goharbor/prepare:v2.9.2 locally 这时候我们就…

算法思想总结:二分查找算法

创作不易&#xff0c;感谢三连&#xff01;&#xff01; 一、二分查找算法思路总结 大家先看总结&#xff0c;然后再根据后面的题型去慢慢领悟 二、二分查找&#xff08;easy&#xff09; . - 力扣&#xff08;LeetCode&#xff09;二分查找 思路&#xff1a;&#xff08;模…

每日学习笔记:C++ STL 的forward_list

定义 特点 操作函数 元素查找、移除或安插 forward_list::emplace_after arg...指的是元素构造函数的参数&#xff08;0~N个&#xff09; #include <iostream> #include <memory> #include <list> #include <forward_list> using namespace std;class…

海思3516将BT1120改BT656输出大小为720*576

sample_comm_vi.c结构体 VI_DEV_ATTR_S DEV_ATTR_BT656D1_1MUX VI_DEV_ATTR_S DEV_ATTR_BT656D1_1MUX {/* interface mode */VI_MODE_BT656,/* multiplex mode */VI_WORK_MODE_1Multiplex,/* r_mask g_mask b_mask*/{0xFF0000, 0x0},//掩码根据自己实际写/* progess…

基于YOLOv8深度学习的野外火焰烟雾检测系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

如何有效避免团队内耗,提升团队整体效能

团队内耗是一个普遍存在的问题&#xff0c;它可能导致工作效率低下、沟通不畅、成员间的信任缺失&#xff0c;甚至可能导致整个团队的崩溃。 它可能源于成员间的误解、利益冲突&#xff0c;或是个人情绪的波动。 如何避免团队内耗&#xff0c;是每个团队管理者和成员都应该关…

新质生产力

新质生产力是以科技创新为引擎&#xff0c;以新产业为主导&#xff0c;以产业升级为方向&#xff0c;以提升核心竞争力为目标的生产力。它融合人工智能、大数据等数字技术&#xff0c;更强调内在的发展质量&#xff0c;旨在走出一条生产要素投入少、资源配置效率高、资源环境成…

java组合模式揭秘:如何构建可扩展的树形结构

组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将对象组合成树形结构以表示整体/部分层次结构。组合模式使得客户端可以统一对待单个对象和组合对象&#xff0c;从而使得客户端可以处理更复杂的结构。 组合模式的主要组成部分包括&…

在Linux/Ubuntu/Debian中测试USB驱动器(U盘)的速度

如果你想测试USB驱动器的速度&#xff0c;可以使用各种工具和命令来测量读写速度。 用于此目的的一个常用工具是“dd”。 以下是如何使用“dd”执行简单的速度测试&#xff1a; 测试写入速度&#xff1a; 打开终端。 使用以下命令将测试文件写入 USB 驱动器&#xff1a; dd i…

人工智能|机器学习——BIRCH聚类算法(层次聚类)

这里再来看看另外一种常见的聚类算法BIRCH。BIRCH算法比较适合于数据量大&#xff0c;类别数K也比较多的情况。它运行速度很快&#xff0c;只需要单遍扫描数据集就能进行聚类。 1.什么是流形学习 BIRCH的全称是利用层次方法的平衡迭代规约和聚类&#xff08;Balanced Iterative…

LeetCode 2789.合并后数组中的最大元素:贪心(倒序)

【LetMeFly】2789.合并后数组中的最大元素&#xff1a;贪心&#xff08;倒序&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/largest-element-in-an-array-after-merge-operations/ 给你一个下标从 0 开始、由正整数组成的数组 nums 。 你可以在数组上…

selenium启用MS Edge浏览器/下载MS Edge WebDriver

Selenium 是一个用于自动化 web 浏览器的工具&#xff0c;可以用于测试 web 应用程序或执行特定 web 任务。要在 Python 中使用 Selenium 来控制 Edge 浏览器&#xff0c;您需要安装相应的 Selenium 包和 Edge 驱动程序&#xff0c;并编写相应的 Python 代码。# 创建 selenium …

Prompt Engineering(提示工程)

Prompt 工程简介 在近年来&#xff0c;大模型&#xff08;Large Model&#xff09;如GPT、BERT等在自然语言处理领域取得了巨大的成功。这些模型通过海量数据的训练&#xff0c;具备了强大的语言理解和生成能力。然而&#xff0c;要想充分发挥这些大模型的潜力&#xff0c;仅仅…

【计算机视觉】目标跟踪| 光流算法详细介绍|附代码

0、前言 在上篇文章中https://blog.csdn.net/Yaoyao2024/article/details/136625461?spm1001.2014.3001.5501&#xff0c;我们对目标跟踪任务和目标跟踪算法有了大致的了解。今天我们就来详细介绍一下其中的生成式算法的一种&#xff1a;光流法。 在介绍光流法之前&#xff…

SinoDB V16.8 版本新特性

1、Oracle兼容 兼容 with as 语法 兼容 insert all/first 语法 兼容 () 形式的左外连接和右外连接语法 兼容 ROLLUP/CUBE/GROUPING SETS 语法 兼容 create or replace view/trigger/procedure/function/index 语法 兼容 rename procedure/function 语法 2、新增功能 条…

IMX8MM -- Yocto构建遇见的错误及解决方法:

IMX8MM Yocto构建遇见的错误及解决方法&#xff1a; 1 bison-3.0.4 error2 Opencv BB_NO_NETWORK Error &#xff1a;3 Yocto构建时出现U-boot 问题4 Yocto构建时出现Linux kernel编译问题5 wayland-native6 cross-localedef-native7 wayland-protocols8 mesa 硬件&#xff1a;…

《BERT基础教程:Transformer大模型实战》读书笔记

概念 BERT&#xff0c;Bidirectional Encoder Representations from Transformers&#xff0c;多Transformer的双向编码器表示法。 RNN&#xff0c;recurrent neural network&#xff0c;循环神经网络。 LSTM&#xff0c;long short-term memory&#xff0c;长短期记忆网络。…

python类中的def __next__(self):有什么用

在Python中&#xff0c;__next__ 方法是一个特殊方法&#xff0c;它用于实现迭代器协议。当一个对象定义了 __next__ 方法时&#xff0c;这个对象就变成了一个迭代器。迭代器允许你在一个序列&#xff08;比如列表、元组或集合&#xff09;或其他可迭代对象上进行迭代&#xff…

Linux网络配置修改hosts映射文件关闭防火墙

Linux网络配置&系统管理 一、物理机、VMware软件、虚拟机之间的网络关系1.1 总体框架图1.2 为什么物理机、VM软件、客户机之间能够通信?1.3 查看客户机的IP地址ifconfig1.4 小节1.5 修改静态IP地址1.6 测试能不能ping通 二、修改主机名以及hosts映射文件2.1 修改主机名2.1…

机器视觉学习(二)—— 显示图像和视频

一、获取图像 要使用OpenCV获取图像&#xff0c;你需要安装OpenCV库并学习基本的OpenCV函数。下面是一些获取图像的基本步骤&#xff1a; 导入必要的库&#xff1a;import cv2 读取图像&#xff1a;image cv2.imread("image.jpg") 这将从指定路径读取图像&#xf…