283. 移动零

题目

  • 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

    请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:

输入: nums = [0]
输出: [0]

python

法一、暴力法

  • 遍历找到零元素,并暂时保存,然后在零元素往后的都前移一位,最后在给最后一位赋给暂存的值
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        for i in range(n):
            if nums[i] == 0:
                
                for j in range(i+1,n):
                    nums[j-1] = nums[j]
                    j += 1
            nums[n-1] = 0
            i +=1
  • 错误:当测试用例刚好有两个挨着的0元素时就会报错。
  • 原因:当遇到第一个0元素时,0元素后面的依次往前一位,最后一位补0,然后进行i+1进行判断,此时,第二个0元素补在了第一个0元素原来的位置,i+1直接跳过了第二个0元素的判断,导致出错。
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        i = 0
        while i < n:
            if nums[i] == 0:
                for j in range(i+1, n):
                    nums[j-1] = nums[j]
                nums[n-1] = 0
                if nums[i] != 0 and i > 0:
                    i += 1
                else:
                    i = i
                    if i < 0:  # 处理i小于0的情况
                        i = 0
            else:
                i += 1
  • 超出时间限制
  • 该方法没有成功解决问题(条件判断存在逻辑矛盾),欢迎大家多多指教

法二、双指针

class Solution:
    def moveZeroes(self, nums):
        i = 0
        j = 0
        n = len(nums)
        
        for i in range(n):#把数组中不是0元素的往前移
            nums[j] = nums[i]
            if nums[i] != 0:#当元素不为0时j才往后移一位,,是0时不动等着nums[j] = nums[i]不为0的替代
                j += 1  #j最终停在最后一个不为0的元素
        
        while j < n:#剩余的位置全部补0
            nums[j] = 0
            j += 1

法三、pop+append

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        n = len(nums)
        i = 0
        while i < n:
            if nums[i] == 0:
                nums.pop(i)#将其从数组中移除
                nums.append(0)#将零追加到数组的末尾
                n -= 1#.pop(i) 将零元素从数组中移除,导致数组的长度减少了1。为了确保循环在正确的范围内进行迭代,需要相应地更新 n 的值。
            else:#如果当前元素不是零
                i += 1#则将索引 i 的值增加 1,以继续下一轮迭代

JavaScript

法一:暴力--存在很大问题

  • 遍历遇到0就把后面的元素往前覆盖,在末尾push(0)
  • 问题:无法处理连续的零的情况,push会改变数组长度,影响索引。
var moveZeroes = function(nums) {
    //遍历遇到0就把后面的元素往前覆盖,在末尾push(0)
    //问题:往前覆盖的时候数组长度会缩短
    for(let i=0;i<nums.length;i++){
        if(nums[i]==0){
            nums.push(0)
            for(let j=i;j<nums.length-1;j++){//范围也有问题,nums.length-1保证nums[j+1]不超出,但是会少一位数组元素
                nums[j]=nums[j+1]
            }
            i=i-1//i为0时减1为负数
        }
    }
    return nums
}

法二:filter过滤0---会改变原数组

  • 思路:使用filter过滤0,根据过滤前后的数组长度差确定在数组后push多少个0
  • 问题:首先,使用 filter 方法会创建一个新的数组并赋值给 nums,这会导致原数组的引用丢失。可以把过滤后的数组赋给一个新数组操作,但是不符合题意不是对原数组进行操作
var moveZeroes = function(nums) {
    //使用filter
    //问题:使用 filter 方法会创建一个新的数组并赋值给 nums,这会导致原数组的引用丢失。
    //接下来对 nums 的所有操作都在新的数组上进行,而不是原始数组。
    let l1=nums.length
    nums=nums.filter(function(item){
        return item !==0
    })
    let l2=nums.length
    let cnt=l1-l2
    while(cnt!=0){
        nums.push(0)
        cnt--
    }
    return nums
};

法三:双指针冒泡排序思想

var moveZeroes = function(nums) {
   //双指针冒泡
   for(let i=0;i<nums.length;i++){
    for(let j=i;j<nums.length;j++){
        if(nums[i]==0){//如果当前值为0就与后一个值交换
            let t=nums[i]
            nums[i]=nums[j]
            nums[j]=t
        }
    }
   }
   return nums
};

法四:双指针

  • 思路:一个指针从头开始用来确定不为0的元素放置的位置,另一个指针用来找到不为0的数,将不为0的数放到第一个指针的位置。第二个指针遍历到尾时结束,第一个指针后面到数组末尾全部添加0。
var moveZeroes = function(nums) {
  let a=0//指针一确定非0元素放置的位置
    for(let i=0;i<nums.length;i++){
        if(nums[i]!==0){//找到非0元素
            nums[a]=nums[i]//赋值给指针一对应的位置
            a++
        }
    }
    for(let i=a;i<nums.length;i++){
        nums[i]=0
    }
    return nums
};
posted @   Frommoon  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示