LeetCode移动零(Move Zeroes)代码判定删0却误删1问题咨询
问题根因
你对Python列表的remove()方法的功能理解有误:
list.remove(参数)接收的参数是要删除的元素值,不是元素的索引下标。调用该方法后,Python会遍历列表,删除第一个和传入参数值相等的元素。你代码里传入的是索引变量i,才会出现不符合预期的删除结果。
对应你给出的运行日志,错误发生的具体流程:
第二次进入if判断分支时,
i=1,此时nums[i]确实是值为0的元素,你打印的removed 0是取的nums[i]的值没问题,但接下来你调用了nums.remove(i),也就是nums.remove(1),程序会去当前列表[1, 0, 3, 12]里找第一个值等于1的元素(也就是索引0位置的1)删除,所以删除后列表变成了[0, 3, 12],这就是你看到的“误删元素1”的原因。
额外注意事项
你当前的代码还有两个不符合LeetCode题目要求的问题:
- 题目要求原地修改输入的
nums数组,你方法第一行写的nums = [0, 1, 0, 3 ,12]是把形参的引用重新指向了自定义的新列表,根本不会修改传入的原数组,提交后无法通过测试用例。 - 用
remove/del删除列表元素的时间复杂度是O(n),整套算法的时间复杂度会达到O(n²),更推荐用双指针法实现O(n)时间复杂度的原地修改方案。
修正后的可运行参考代码
如果你要沿用你当前的删除后补0的逻辑,只需要把nums.remove(i)改成del nums[i]即可(del nums[索引]是删除指定索引位置的元素):
from typing import List class Solution: def moveZeroes(self, nums: List[int]) -> None: k = 0 i=0 while i < len(nums): if nums[i] == 0: k += 1 del nums[i] else: i += 1 for j in range(k): nums.append(0)
更高效的双指针实现:
from typing import List class Solution: def moveZeroes(self, nums: List[int]) -> None: # slow指针指向最后一个非零元素的下一个位置 slow = 0 for fast in range(len(nums)): if nums[fast] != 0: nums[slow], nums[fast] = nums[fast], nums[slow] slow += 1
内容的提问来源于stack exchange,提问作者jaydeva ahirrao
相关产品推荐
相关产品推荐

