【小白友好】python leetcode 27 remove element

Problem: 27. 移除元素

工程思想

用一些python已有的工具:

while val in nums:nums.remove(val)

但是我们显然不要这么做对不对!

从零开始

看题目是要in place,则考虑交换咯。
要把不等于val的移到前面,则考虑把数组分成2部分,只要把等于val的全部交换到后面的部分就可以了。

这种就考虑用2个指针,i从前向后扫元素,把等于val的交换走,now_idx从后向前走,记录等于val的位置。

不假思索的话,代码应该是这样:

# 这是错的!
def removeElement(self, nums: List[int], val: int) -> int:now_idx=len(nums)-1 # 从后向前扫cnt=0for i in range(len(nums)): # i从前向后扫if nums[i]==val:# 交换tmp=nums[i]nums[i]=nums[now_idx]nums[now_idx]=tmpcnt+=1 # 记录val值个数now_idx-=1 # 从后向前扫# 返回非val值的个数return len(nums)-cnt
  • 等于val的数字在交换后仍然会被i再次扫到,会导致重复交换:[val,a,b,c]交换成[c,a,b,val]后,i=3的时候val还会被i找到,此时now_idx=2,交换后导致错误。
  • 在用例[a,b,c,val,c,val]时,i扫到val的时候,val会与后面的val交换,然后i++和now_idx–,导致交换错误。

小白改进

第一点:考虑记录一下一共要交换多少次val,用target_num记录,交换次数到了就不再继续走了,直接退出,因为所有等于val的都已经交换过了

第二点:考虑在交换的时候直接找到数组后半部分的第一个不等于val的值,这样就不会把val交换到前面。

class Solution:def removeElement(self, nums: List[int], val: int) -> int:       now_idx=len(nums)-1cnt=0target_num=0# 记录要交换多少次for num in nums:if num==val:target_num+=1for i in range(len(nums)):# 加入target num!=0,等于0的时候就不需要交换了if target_num!=0 and nums[i]==val: # 找到最前面的不是val的,并且每找到一个val,target num都要减少1,cnt要增加1while nums[now_idx]==val:now_idx-=1cnt+=1target_num-=1if target_num==0:# 此时已经结束了return len(nums)-cnttmp=nums[now_idx]nums[now_idx]=nums[i]nums[i]=tmpcnt+=1now_idx-=1target_num-=1return len(nums)-cnt           

提交的最后

上述基本上能过了,但是还有特殊情况要考虑,比如空值、0等等情况。
然后把想出来的都列一下看看情况。
nums=[]不可能,val值都没有。
nums=[1], val=1,此时return的值应当是0,也还没问题。

提交下,过了,用时击败82%。

技巧

但再想想,是不是这样我的指针可以换一种方式进行(所谓快慢指针):
不妨考虑快慢指针,一般使用起来都是O(n),结束条件几乎都是快指针遍历结束,慢指针恰好在边界。不同点是慢指针的条件各不相同。

根据小白解法,我们让快指针去指向判定当前元素是否能进入左侧要保留部分的位置,慢指针指向保留部分的最后一个位置。也就是快指针做条件判断,慢指针做位置标识。

那么用什么条件作为快指针条件呢?
回归题意,我们希望左侧的都是不等于val,这样只要nums[fast]!=val,就可以把fast元素放到左侧了。

class Solution:def removeElement(self, nums: List[int], val: int) -> int:slow=0cnt=0for fast in range(len(nums)):if nums[fast]!=val:# swaptmp=nums[fast]nums[fast]=nums[slow]nums[slow]=tmpslow+=1return slow

这样做不需要先统计target num,直接以快指针走到最后为结束条件;而且不需要再在交换的时候寻找位置了,因为慢指针的位置就是我想要交换的位置。

提交后也过了。但是效率不如第一版的。

小改进

由于题目说后面部分的数组的值是任意的就可以,只要返回有效数组长度就行,所以我们可以不交换,直接丢弃掉等于val值的数(换句话说,只保留前半部分的不等于val的数)。

这个简单,把上面的

tmp=nums[fast]
nums[fast]=nums[slow]
nums[slow]=tmp
# 改成
nums[slow]=nums[fast]

总结

其实都是双指针的思路,只不过一开始naive的双指针写起来比较啰嗦,而改进后的双指针写起来简洁。

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

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

相关文章

MySQL sql注意点

为何写这篇博客,源于工作时虽然写了大量sql语句包括复杂sql。可是一但脱离sql执行环境和运行结果。发现很多东西只是在尝试中解决了问题,但这还远远不够。 本文列取了常用但是容易遗漏的一些知识点。另外关键词一般大写,为了便于阅读所以很多…

Unity 2021.3发布WebGL设置以及nginx的配置

使用unity2021.3发布webgl 使用Unity制作好项目之后建议进行代码清理,这样会即将不用的命名空间去除,不然一会在发布的时候有些命名空间webgl会报错。 平台转换 将平台设置为webgl 设置色彩空间压缩方式 Compression Format 设置为DisabledDecompre…

XGB-11:随机森林

XGBoost通常用于训练梯度提升决策树和其他梯度提升模型。随机森林使用与梯度提升决策树相同的模型表示和推断,但使用不同的训练算法。可以使用XGBoost来训练独立的随机森林,或者将随机森林作为梯度提升的基模型。这里我们专注于训练独立的随机森林。 XG…

解决Mysql的Access denied for user权限不足问题

当用客户端工具连接数据库 以root 用户登录后 无法给相关用户授权数据库等操作: 原因: root%表示 root用户 通过任意其他端访问操作 被拒绝! 授权即可: 登录server端: mysql -uroot -pxxxxx(使用账号密码登录linux mysql服务内部) 然后输入如下sql命令…

Sora:开启视频生成新时代的强大人工智能模型

目录 一、Sora模型的诞生与意义 二、Sora模型的技术特点与创新 三、Sora模型的应用前景与影响 四、面临的挑战与未来发展 1、技术挑战 2、道德和伦理问题 3、计算资源需求 4、未来发展方向 随着信息技术的飞速发展,人工智能(AI)已成为…

vue3中使用vuedraggable实现拖拽el-tree数据进分组

看效果: 可以实现单个拖拽、双击添加、按住ctrl键实现多个添加,或者按住shift键实现范围添加,添加到框中的数据,还能拖拽排序 先安装 vuedraggable 这是他的官网 vue.draggable中文文档 - itxst.com npm i vuedraggable -S 直接…

tomcat通过JAVA_OPTS注入自定义变量 —— 筑梦之路

背景说明 tomcat部署的java应用在k8s集群或容器中,想要给tomcat传自定义变量,应该如何实现? 解决方法 1. 在k8s集群或容器环境中通过env或者configmap方式添加自定义的环境变量 比如: my_key: aaaa 2. tomcat下新增脚本&am…

拓扑空间简介

目录 介绍集合论与映射映射相关定义映射(map)映射的一种分类:一一的和到上的 拓扑空间背景介绍开子集开子集的选择 拓扑拓扑空间常见拓扑拓扑子空间同胚其他重要定义 开覆盖紧致性有限开覆盖紧致性 R R R的紧致性 习题 介绍 这是对梁灿彬的《…

shim error: docker-runc not installed on system

问题描述:shim error: docker-runc not installed on system 解决办法: 方式一: cd /usr/libexec/docker/sudo ln -s docker-runc-current docker-runc 方式二: vi /etc/docker/daemon.json # 添加内容如下: {"…

【软件架构】01-架构的概述

1、定义 软件架构就是软件的顶层结构 RUP(统一过程开发)4 1 视图 1)逻辑视图: 描述系统的功能、组件和它们之间的关系。它主要关注系统的静态结构,包括类、接口、包、模块等,并用于表示系统的组织结构…

全栈笔记_工具篇(nvm免安装版自动配置,无需手动设置环境变量)

将免安装压缩包nvm-noinstall.zip解压到指定目录,如:C:\nvm 修改install.cmd: @echo off set /P NVM_PATH="Enter the absolute path where the nvm-windows zip file is extracted/copied to: " set NVM_HOME=%NVM_PATH% setx NVM_HOME "%NVM_HOME%"fo…

C++入门学习(三十六)函数的声明

程序是自上而下运行的&#xff0c;比如我下面的代码&#xff1a; #include <iostream> #include<string> using namespace std;int main() { int a1; int b2;int sumaddNumbers(a,b); cout<<sum;return 0; }int addNumbers(int a, int b) { int sum …

MFC 配置Halcon

1.新建一个MFC 工程&#xff0c;Halcon 为64位&#xff0c;所以先将工程改为x64 > VC 目录设置包含目录和库目录 包含目录 库目录 c/c ->常规 链接器 ->常规 > 链接器输入 在窗口中添加头文件 #include "HalconCpp.h" #include "Halcon.h"…

简单讲解并梳理微信小程序默认几个文件和文件夹结构及其作用

那么 我们来说一下 小程序整个项目结构 它各个文件 和 整体结构 这是我们新创建的一个小程序项目 我们从上到下 分别来看一下 这些文件和目录结构的作用 首先是 pages 它的作用在于存储整个项目所有的 page页面文件 我们小程序官方 是推荐我们将所有page 界面都放在pages目录…

稀疏计算、彩票假说、MoE、SparseGPT

稀疏计算可能是未来10年内最有潜力的深度学习方向之一&#xff0c;稀疏计算模拟了对人脑的观察&#xff0c;人脑在处理信息的时候只有少数神经元在活动&#xff0c;多数神经元是不工作的。而稀疏计算的基本思想是&#xff1a;在计算过程中&#xff0c;将一些不重要的参数设置为…

一招解决 vue数据格式校验时候 async-validator: [‘XXXX is not a number‘]

在vue中 amt数字需要进行纯数字校验&#xff1a; 格式都没问题&#xff0c;但是输入纯数字也会报错&#xff0c;报错如下&#xff1a; async-validator:[‘amt is not a number’] 网上找了一些&#xff0c;但是均为能奏效&#xff0c;尝试如下&#xff1a; 尝试1&#x…

软件保护技术

本文已收录至《全国计算机等级考试——信息 安全技术》专栏 软件保护 软件保护技术其实是一个很大的概念&#xff0c;技术上分为很多不同的分支&#xff0c;主要包括加密、防篡改、软件水印、软件多样化、反逆向技术、虚拟机、基于网络的保护和基于硬件的保护等。 加密是指对…

基于Python网络爬虫的IT招聘就业岗位可视化分析推荐系统

文章目录 基于Python网络爬虫的IT招聘就业岗位可视化分析推荐系统项目概述招聘岗位数据爬虫分析系统展示用户注册登录系统首页IT招聘数据开发岗-javaIT招聘数据开发岗-PythonIT招聘数据开发岗-Android算法方面运维方面测试方面招聘岗位薪资多维度精准预测招聘岗位分析推荐 结语…

FlinkCDC详解

1、FlinkCDC是什么 1.1 CDC是什么 CDC是Chanage Data Capture&#xff08;数据变更捕获&#xff09;的简称。其核心原理就是监测并捕获数据库的变动&#xff08;例如增删改&#xff09;&#xff0c;将这些变更按照发生顺序捕获&#xff0c;将捕获到的数据&#xff0c;写入数据…

TensorFlow 的特点和应用场景介绍

TensorFlow是一个开源的机器学习框架,最初由Google Brain团队开发并于2015年发布。它被设计用于构建、训练和部署各种机器学习算法和深度神经网络模型。TensorFlow具有以下特点: 强大的计算图:TensorFlow使用计算图来表示复杂的计算任务。计算图是由节点(表示操作)和边(表…