力扣面试经典算法150题:移除元素

news2025/2/28 12:40:41

移除元素

今日的题目依旧是力扣面试经典算法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];
                // 只有元素不同时,才放入元素并更新指针2
                j++; 
            }
            // 更新指针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)。
  • 简单易实现:双指针法的逻辑简单,易于理解和实现

总结

实际上上一篇文章中的题目,也是用的双指针法。

双指针法在处理数组的算法题时,是比较常见且又好用的一种解决办法。

熟练使用可以更好的帮助在数组方面的问题!

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

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

相关文章

cpu问题排查——mpstat

mpstat是sysstat包中用于linux下排查、监控cpu的一个工具。可从该工具体现出程序中断情况、cpu负载情况等。 用法 mpstat [ options ] [ <interval> [ <count> ] ] 命令参数 -P { <cpu_list> | ALL } : ALL表示所有cpu的平均损耗信息&#xff0c;<cpu_…

PXE 服务器搭建——启动界面设计实验

环境准备&#xff1a; 前期准备&#xff1a; 解决 kickstart 实验出现的 DHCP 的问题-CSDN博客 http://t.csdnimg.cn/5vZP0 当前准备&#xff1a; 两台虚拟机&#xff1a;RHEL7 OpenEuler(作为测试机器使用) ip&#xff1a;172.25.254.100 yum install syslinux.x…

Go语言标准库中的双向链表的基本用法

什么是二分查找区间&#xff1f; 什么是链表&#xff1f; 链表节点的代码实现&#xff1a; 链表的遍历&#xff1a; 链表如何插入元素&#xff1f; go语言标准库的链表&#xff1a; 练习代码&#xff1a; package mainimport ("container/list""fm…

如何在Python中诊断和解决内存溢出问题

python的内存溢出即程序在申请内存后未能正确释放&#xff0c;导致随着时间推移占用的内存越来越多&#xff0c;以下是一些可能导致内存溢出的原因&#xff1a; 1、循环引用&#xff1a;当对象之间形成循环引用&#xff0c;并且这些对象定义了__del__方法时&#xff0c;Python…

证券行业容器云平台建设之GPU池化建议

随着分布式微服务化技术的广泛使用&#xff0c;用户对于容器系统的需求急剧增加。证券行业在近几年开始着手引入企业级容器云平台。在AIGC的大环境下&#xff0c;证券行业正以数据中台、智能中台为核心&#xff0c;在营销、投顾、投研、风控等多个领域进行智能化升级&#xff0…

MYSQL主库切换binlog模式后主从同步错误

MYSQL主库切换binlog模式后主从库同步错误的问题 在使用FlinkSQL的mysql-cdc连接器来监听MySQL数据库时&#xff0c;通常需要将MySQL的binlog模式设置为ROW模式。然而&#xff0c;在实际项目中&#xff0c;可能会遇到如下问题&#xff1a; 当我们将MySQL主库的binlog模式从STA…

计算机网络408考研 2018

1 计算机网络408考研2018年真题解析_哔哩哔哩_bilibili

【sdk】- 对接阿里云抠图

文档地址&#xff1a;https://help.aliyun.com/zh/viapi/use-cases/general-image-segmentation?spma2c4g.11186623.0.0.3814173cenldIs java对接阿里云的通用分割&#xff0c;将代码原封不动复制进来&#xff0c;执行结果失败&#xff0c;咨询阿里云的人员之后&#xff0c;由…

JavaEE: Thread类

Thread的常见构造方法 Thread的常见属性 ID 是线程的唯一标识,不同线程不会重复名称是在使用各种调试工具时会用到的状态表示线程当前所处的情况优先级高的线程理论上来说更容易被调度到关于后台线程,需要记住:JVM会在一个进程的所有非后台线程结束后,才会结束运行是否存活,即r…

爱可声助听器:在全球听力市场中破冰前行

早在2021年&#xff0c;全球助听器市场规模就已经达到了101亿美元&#xff0c;Grand View Research数据显示&#xff0c;这一规模会持续增大&#xff0c;在未来的6年间&#xff0c;该数据将以4.9%的复合年增长率&#xff08;CAGR&#xff09;增长。 作为发展中国家&#xff0c…

【SpringBoot】自定义注解终极升级版<i18n国际化>方案源码Copy

零、前言 在后端对于 SpringBoot 的 数据库数据&#xff0c;需要国际化的字段和主要显示字段是分离的&#xff0c;为了避免大耦合性&#xff0c;与用户端的国际化字段处理问题&#xff0c;统一采用主要显示数据的实体字段。为此&#xff0c;我设计了一套解决方案&#xff0c;通…

leetcode-240. 搜索二维矩阵 II

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10…

使用Spring AI 、 Qdrant 和 Ollama 实现完全本私有化的RAG应用

使用Spring AI 、 Qdrant 和 Ollama 实现完全本私有化的RAG应用 迄今为止&#xff0c;Python 一直是实现检索增强生成&#xff08;RAG&#xff09;应用程序的首选语言&#xff0c;几乎成为开发大型语言模型&#xff08;LLM&#xff09;应用程序的默认选择。然而&#xff0c;对于…

WPF 依赖属性 IsHitTestVisible

IsHitlTestVisible 仅影响本身的元素&#xff08;含内部包含的子元素&#xff09;&#xff0c;不影响父元素效果&#xff0c;且事件会传递到父元素。 Eg&#xff1a; 如父元素有click事件&#xff0c; 子元素设置了IsHitTestVisiblefalse&#xff0c; 当鼠标单击这个子元素时&…

openssl 制作 信用库与服务证书

文章目录 前言openssl 制作 信用库与服务证书1. CA 证书2. 服务器证书/秘钥库3. 创建信用库4. 注意事项 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会…

【JS】一篇BOM详解笔记 | b站李立超

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、BOM简介&#xff1a;☀️☀️☀️2.1 BOM是什么及有什么用2.2 BOM对象有哪些 三、BOM各类对象讲解&#xff1a;☀️☀️☀️3.1 Navigator3.2 Location3.3 History 三、补充知识&#x1f680;&#x1f680;&#…

尚硅谷谷粒商城项目笔记——六、使用navciat连接docker中的mysql容器【电脑CPU:AMD】

六、使用navciat连接docker中的mysql容器 注意&#xff1a; 因为电脑是AMD芯片&#xff0c;自己知识储备不够&#xff0c;无法保证和课程中用到的环境一样&#xff0c;所以环境都是自己根据适应硬件软件环境重新配置的&#xff0c;这里的虚拟机使用的是VMware。 1navicat免费…

浴室柜哪个牌子质量好性价比高 | 提亮空间,点缀生活!

摘要&#xff1a;作为浴室的标配&#xff0c;浴室柜不仅是重要的收纳家具&#xff0c;也是最能体现卫浴空间和美感的存在。浴室柜看似平凡&#xff0c;却在无形之中散发出自身的魅力&#xff0c;为浴室颜值加分。浴室柜哪个品牌好&#xff1f;无论是注重外观的你&#xff0c;还…

《计算机组成原理》(第3版)第4章 存储器 复习笔记

第4章 存储器 一、概述 &#xff08;一&#xff09;存储器分类 1&#xff0e;按存储介质分类 &#xff08;1&#xff09;半导体存储器&#xff1b; &#xff08;2&#xff09;磁表面存储器&#xff1b; &#xff08;3&#xff09;磁芯存储器&#xff1b; &#xff08;4&…

面试笔记8.6

缓存 1.如何保证redis与数据库一致性 redis面试&#xff1a;如何保证缓存和数据库数据的一致性&#xff1f;_使用update更新数据,json缓存不更新-CSDN博客 如果先删除缓存&#xff0c;再删除数据库&#xff0c;数据不一致&#xff0c; 解决 删 1.先操作缓存但不删除缓存&…