283.移动零 关于列表list与remove原理*****(简单)
题目:
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
注意,该题目要求不开辟行的数组空间,在原数据上进行操作。
示例:
输入:[0,1,0,3,12]
输出:[1,3,12,0,0]
说明:
- 必须在原数组上操作,不能拷贝额外的数组。
- 尽量减少操作次数。
自我解答:
思路1:如同冒泡算法那样,用两个for循环进行遍历,将0依次移动到列表最后面。
缺点:复杂度太高,n^n,上传答案时会报错。
思路2:for循环遍历数组,当该数为0时,remove移除该数,
在这里有两个python知识点。
原本,我是希望先把所有的0删除后,再往后面添加同样数量的0,但是,发现删不掉0的情况
list1 = [0,2,0,0,8,0,8,0,1]
class Solution2:
def moveZeroes(self, nums):
for i in nums:
if i ==0:
nums.remove(i)
# nums.append(0)
print(nums) s = Solution2()
s.moveZeroes(list1)
#[2, 8, 8, 0, 1]
百度了一番发现了其中的奥秘:
for循环原理
python中for循环是遍历所有nums下标,然后根据下标遍历列表。
当列表边遍历边删除的时候,会出现漏遍历的情况,当列表中的数字被删除时,后面的数字会跟上,他们的下标也会跟着改变,如
list1=[1,2,3,4,5,6]
for i in list1:
remove(i)
#[2,4,6]
因为删除了1,所以2代替了原来1的位置,for循环就会寻找现在列表中的2位置是谁,很显然2是数字3.
但是又有一个问题,难道在遍历了6之后还有3个下标没有遍历会怎么处理呢。
这就涉及到for循环的内部原理,其中有__next__方法就是获取下一个元素,当获取不到时就会报错,然后内部处理异常,停止取值。
remove原理
但光是这样的话,上述代码最后执行的结果不就是[2,0,8,8,0,1]吗。
原来remove的删除原因是删除当前列表中第一个匹配的值,所以当遍历到后面的0时会删除前面跳过的0,但是遍历到的0总是比较少的,所以最后总会漏掉1到2个。
解决方法:
1.这个方法不是很完美,因为方法不变,只是边删除0边在后面添加0,这就使得原先没有遍历结束的下标全部遍历,所以不妨换一个角度想。
我们每遍历到一个0就获得删除一个0的机会(remove),每删除一个0就会添加一个0,所以列表总长度不变,最后原先列表遍历结束后,就会遍历添加进去的0,直到遍历结束。
或者理解为保证列表长度不变的情况下,尽可能的删掉队列中所有的0,那这些0到哪里去了呢,显然就是append的哪些:
list1 = [0,2,0,0,8,0,8,0,1]
class Solution2:
def moveZeroes(self, nums):
for i in nums:
if i ==0:
nums.remove(i)
nums.append(0)
print(nums)
#[2, 8, 8, 1, 0, 0, 0, 0, 0]
2,从后往遍历。
这种方法适用于任何边循环边改变列表元素的问题,使用切片中默认值的方式:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
for i in nums[::-1]:
if i==0:
nums.remove(i)
nums.append(0)
添加的0和剔除的0在总列表的最后,不会影响for循环中即将遍历的值.
官方解答:
这个题目的标签是数组与双指针。可以这么做:
定义一个长指针和一个短指针。
长指针用来判断列表中的0元素直到最后,短指针则用来记录非0的值到列表中。
最后再在短指针的最后将所有的值改成0,实现该功能。
list1 = [0,2,0,0,8,0,8,0,1]
class Solution:
def moveZeroes(self, nums):
long_t = 0
short_t = 0
while long_t < len(nums):
if nums[long_t]!=0:
nums[short_t] = nums[long_t]
long_t +=1
short_t +=1
else:
long_t +=1
while short_t <len(nums):
nums[short_t] = 0
short_t += 1
print(nums) #[2, 8, 8, 1, 0, 0, 0, 0, 0]
python中实现指向数组的指针都可以使用这种方法,这种方法在执行时间的角度来讲也比较合理。
283.移动零 关于列表list与remove原理*****(简单)的更多相关文章
- 前端与算法 leetcode 283. 移动零
目录 # 前端与算法 leetcode 283. 移动零 题目描述 概要 提示 解析 解法一:暴力法 解法二:双指针法 算法 传入[0,1,0,3,12]的运行结果 执行结果 GitHub仓库 # 前 ...
- 【Leetcode】【简单】【283. 移动零】【JavaScript】
题目描述 283. 移动零 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12]输出: [1,3,12,0,0] 说 ...
- 在Python的列表中利用remove()方法删除元素的教程
在Python的列表中利用remove()方法删除元素的教程 这篇文章主要介绍了在Python的列表中利用remove()方法删除元素的教程,是Python入门中的基础知识,注意其和pop()方法的区 ...
- Java实现 LeetCode 283 移动零
283. 移动零 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必 ...
- 【LeetCode】283.移动零
283.移动零 知识点:数组:双指针: 题目描述 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例 输入: [0,1,0,3,12] 输出: [1, ...
- Android零基础入门第11节:简单几步带你飞,运行Android Studio工程
原文:Android零基础入门第11节:简单几步带你飞,运行Android Studio工程 之前讲过Eclipse环境下的Android虚拟设备的创建和使用,现在既然升级了Android Studi ...
- 1102: 零起点学算法09——继续练习简单的输入和计算(a-b)
1102: 零起点学算法09--继续练习简单的输入和计算(a-b) Time Limit: 1 Sec Memory Limit: 520 MB 64bit IO Format: %lldSub ...
- python(leetcode)-283移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数组上操作, ...
- LeetCode(283. 移动零)
问题描述 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数 ...
随机推荐
- 快速傅里叶变换(FFT)学习笔记
定义 多项式 系数表示法 设\(A(x)\)表示一个\(n-1\)次多项式,则所有项的系数组成的\(n\)维向量\((a_0,a_1,a_2,\dots,a_{n-1})\)唯一确定了这个多项式. 即 ...
- 20191028 Codeforces Round #534 (Div. 1) - Virtual Participation
菜是原罪. 英语不好更是原罪. \(\mathrm{A - Grid game}\) 题解 \(4 \times 4\) 的格子,两种放法. 发现这两种在一起时候很讨厌,于是强行拆分这个格子 上面 \ ...
- 【ECNU620】数学题(结论题)
点此看题面 大致题意: 求\((n-1)!\ mod\ n\)的值. 大力猜结论 首先,看到样例,我们可以猜测: 当\(n\)为质数时,答案为\(n-1\). 当\(n\)为合数时,答案为\(0\). ...
- backbone 路由传参(可选)
因为维护公司的老项目而接触到backbone.以前是只闻其名,未见其码. 因为其他项目需要跳转到本项目的某个页面,但是需要UI改变. 考虑的方法是给路由添加一个可选参数.代码如下: 正常路由: rou ...
- JS中的undefined,null,"",0,'0'和false
){ console.log(); } '){ console.log() } '){ console.log() } if(false==0.0){ console.log() } if(false ...
- 在ASP.Net Core 中使用枚举类而不是枚举
前言:我相信大家在编写代码时经常会遇到各种状态值,而且为了避免硬编码和代码中出现魔法数,通常我们都会定义一个枚举,来表示各种状态值,直到我看到Java中这样使用枚举,我再想C# 中可不可以这样写,今天 ...
- idea修改svn地址
1.不能直接修改idea中的svn路径 2.需要先修改小乌龟地址,先找到本地的项目文件右键
- php explode容易犯的错误
php explode容易犯的错误 <pre> $pos = strpos($v, 'Controller'); if (is_numeric($pos)) { $kongzhiqifeg ...
- oracle排序子句的特殊写法与ORA-01785错误
刚刚写的SQL语句在执行的时候报[ORA-01785: ORDER BY item must be the number of a SELECT-list expression]错误,于是自己百度了一 ...
- 【LOJ#3144】[APIO2019]奇怪装置(数论)
[LOJ#3144][APIO2019]奇怪装置(数论) 题面 LOJ 题解 突然发现\(LOJ\)上有\(APIO\)的题啦,赶快来做一做. 这题是窝考场上切了的题嗷.写完暴力之后再推了推就推出正解 ...