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] 说明: 必须在原数 ...
随机推荐
- vue中keepAlive的使用
在开发中经常有从列表跳到详情页,然后返回详情页的时候需要缓存列表页的状态(比如滚动位置信息),这个时候就需要保存状态,要缓存状态:vue里提供了keep-alive组件用来缓存状态.可以用以下几种方案 ...
- flutter,SliverPersistentHeader实现Tab顶部吸附固定效果
直接上代码啦 import 'package:flutter/material.dart'; class StickyDemo extends StatefulWidget { @override _ ...
- 剑指offer:矩阵中的路径(递归回溯法DFS类似迷宫)
1. 题目描述 /* 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径. 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子. 如果一条 ...
- C# 原子操作理解
C#内置提供的原子操作 Interlocked.Increment:以原子操作的形式递增指定变量的值并存储结果. Interlocked.Decrement:以原子操作的形式递减指定变量的值并存储结果 ...
- 【08月14日】A股ROE最高排名
个股滚动ROE = 最近4个季度的归母净利润 / ((期初归母净资产 + 期末归母净资产) / 2). 查看更多个股ROE最高排名 兰州民百(SH600738) - ROE_TTM:86.45% - ...
- golang--单元测试综合实例
实例说明: (1)一个Monster结构体,字段Name,Age,Skill (2)Monster有一个Store方法,可以将一个Monster对象序列化后保存在文件中: (3)Monster有一个R ...
- (十九)golang--函数参数的传递方式
两种传递方式: 值传递:值类型参数默认 引用传递:引用类型参数默认 一般来说,地址传递效率高,因为数据量小. 值类型:int.float.bool.string.数组.结构体: 引用类型:指针.切片. ...
- mybatis的参数传递
mybatis的参数传递分为两种:1.单参数传递 2.多参数传递 单参数 mybatis会直接取出参数值给Mapper文件赋值 例子如下: 1.Mapper文件内容如下: public void d ...
- 将Excel表格数据转换成Datatable
/// <summary> /// 将Excel表格数据转换成Datatable /// </summary> /// <param name="fileUrl ...
- CD 基金会、Jenkins、Jenkins X、Spinnaker 和 Tekton 的常问问题
转载:https://mp.weixin.qq.com/s/bQLqGrCM9NZYI0Njlu4N-w FAQ 什么是持续交付(CD)? CD是一种软件工程方法,团队在短周期内生成软件,确保软件可以 ...