news 2026/5/16 1:30:54

LeekCode面试经典150题之移除元素

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeekCode面试经典150题之移除元素

面试经典150题之移除元素

一、题目

1.题目描述

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
返回 k。

2.题目分析

这是一道移除数组中元素的题目,我们需要做到原地移除,但是题目说了不会去管超过我们返回给它的值之后的数字,因此我们有两种思路:一种是直接将所有等于val的数字全部都移动到第k个数之后(并且这种方法是基于交换的,即整个数组包含的数是没有变的),另一种是将所有不等于val的数直接排到前K个,而不管k之后是否有不等于val的数。下面我将介绍4种方法,并且对我踩的一些坑也简要的说明。

二、具体方法

1.直接用remove()函数解决

whilevalinnums:nums.remove(val)returnlen(nums)

由于remove()函数能够直接删去列表中第一个匹配的值,因此直接适用能够删去列表中所有等于val的值。这种方法相对简单,但是前提是我们要知道remove()函数的用法。

2.新列表承接,再替换

num_true=[iforiinnumsifi!=val]foriinrange(len(num_true)):nums[i]=num_true[i]returnlen(num_true)

我们可以用一个全新的列表来讲数组中所有的符合要求的值全部都记录下来,然后再讲这个新的列表的值按顺序插入到原来的列表中去。这种方法也很简单,不太符合题目的要求,因为题目要求原地排序,不过在日常我们自己的代码中需要的时候可以使用。

下面我将介绍两种相对来说比较有意思的方法

3.以栈的思维来看数组

defremoveElement(self,nums,val):""" :type nums: List[int] :type val: int :rtype: int """stack_size=0forxinnums:ifx!=val:nums[stack_size]=x stack_size+=1returnstack_size

我们将nums数组看做一个栈,在我们没有看这个数组之前,我们没有确定栈里面的任意一个元素,因此初始的栈的大小为0。然后我们遍历数组的元素,如果这个元素不为val,我们就把这个数组压入栈中,并且将栈的大小也进行相应的调整。最后我们返回栈的大小。

4.双指针置换法

defremoveElement(self,nums,val):""" :type nums: List[int] :type val: int :rtype: int """left=0right=len(nums)-1whileleft<=right:if(nums[left]==val)and(nums[right]!=val):temp=nums[right]nums[right]=nums[left]nums[left]=temp left+=1right-=1elif(nums[right]==val):right-=1else:left+=1returnleft

这个方法的核心思路就是要设立两个指针,一个一开始指向最左端,一个刚开始指向最右端。然后将所有为val的值都移到数组的右边。
如果左指针指向的值为val,且有指针指向的值不为val的话,我们就将左指针指向的值和有指针指向的值交换,并且左指针右移,右指针左移。不论左指针是否为val,只要右指针为val,就将右指针左移。(这里我们可以具体的解释一下:如果左指针指向的数不为val,且右指针指向的值为val的话,当前右指针指向的位置已经为val了,所以我们要往前找到不是val的进行再进行操作。如果左右都是,我们可以通过移动右指针来转换为第一种情况)最后一种情况,也就是左指针指向的不是并且右指针指向的也不是,那么我们将左指针向右移动即可,右指针不需要一定(因为右指针指向的人这个地方还可以换成val,但是现在没有换)
最后结束的条件就是左指针比右指针大了,返回值就为左指针的数值。

三、我踩的坑

我一开始些的代码是下面这样的:

defremoveElement(self,nums,val):""" :type nums: List[int] :type val: int :rtype: int """foriinnums:ifi==val:nums.remove(i)returnlen(nums)

乍一看,我的这个代码和前面的第一种方法的代码很像,但是为什么我这样些就不行呢?
因为for i in nums 循环是基于列表迭代器实现的,迭代器会按顺序读取列表的索引(0→1→2→…)。在循环中执行 nums.remove(i) 时,列表长度变短、元素前移,迭代器的指针会跳过部分元素,导致漏删。

后面我又尝试用for i in range (len(nums)):进行迭代 ,但是这样也是错的,一旦在某次循环中又元素删除的话,那么len(nums)就会随着改变,会出现和上面一样的问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 13:12:41

Formily与第三方UI库深度整合:解锁企业级表单开发新范式

Formily与第三方UI库深度整合&#xff1a;解锁企业级表单开发新范式 【免费下载链接】formily &#x1f4f1;&#x1f680; &#x1f9e9; Cross Device & High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue …

作者头像 李华
网站建设 2026/5/11 12:34:34

告别重复劳动:3步掌握卡牌批量生成神器

告别重复劳动&#xff1a;3步掌握卡牌批量生成神器 【免费下载链接】CardEditor 一款专为桌游设计师开发的批处理数值填入卡牌生成器/A card batch generator specially developed for board game designers 项目地址: https://gitcode.com/gh_mirrors/ca/CardEditor 还…

作者头像 李华
网站建设 2026/5/11 16:43:40

如何快速获取阿里云盘Refresh Token:扫码神器完整指南

如何快速获取阿里云盘Refresh Token&#xff1a;扫码神器完整指南 【免费下载链接】aliyundriver-refresh-token QR Code扫码获取阿里云盘refresh token For Web 项目地址: https://gitcode.com/gh_mirrors/al/aliyundriver-refresh-token 想轻松获取阿里云盘的Refresh …

作者头像 李华
网站建设 2026/5/10 4:20:17

SuperCom串口调试工具终极指南:从新手到专家的快速上手攻略

SuperCom串口调试工具终极指南&#xff1a;从新手到专家的快速上手攻略 【免费下载链接】SuperCom SuperCom 是一款串口调试工具 项目地址: https://gitcode.com/gh_mirrors/su/SuperCom SuperCom串口调试工具作为嵌入式开发和硬件调试领域的得力助手&#xff0c;凭借其…

作者头像 李华
网站建设 2026/5/5 23:50:58

虚拟机安装 MySQL/MariaDB的部分方法

本文针对 VMware 中常用的两款 Linux 发行版 ——Rocky Linux&#xff08;RHEL 系&#xff09; 和 Ubuntu&#xff08;Debian 系&#xff09;&#xff0c;讲述部分安装 MySQL/MariaDB 的方法一、Rocky Linux&#xff08;8/9&#xff09;安装 MySQL/MariaDB1.使用官方源步骤 1&a…

作者头像 李华
网站建设 2026/5/15 6:35:15

HEIF Utility:Windows平台HEIF图像处理全攻略

还在为iPhone拍摄的HEIF照片在Windows上打不开而烦恼吗&#xff1f;这款开源工具将彻底解决你的困扰&#xff01;HEIF Utility是专门针对Windows系统打造的HEIF图像处理神器&#xff0c;让你轻松查看和转换苹果HEIF格式图片。 【免费下载链接】HEIF-Utility HEIF Utility - Vie…

作者头像 李华