leetcode 移动零

283. 移动零

已解答

简单

相关标签

相关企业

提示

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

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

进阶:你能尽量减少完成的操作次数吗?

超时代码

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        for m in range(len(nums)):
            for i in range(0,len(nums)-1):
                if nums[i] == 0:
                    for j in range(i,len(nums)-1):
                        case = nums[j+1]
                        nums[j+1] = nums[j]
                        nums[j]=case

        return nums
  • 冗余的嵌套循环

    • 该代码在每次遇到 0 时,都会从当前位置将后面的元素逐个交换。由于 moveZeroes 的任务仅仅是将所有非零元素前移,零元素移动到末尾,过多的循环和交换操作会降低效率。
  • 算法效率低

    • 当前算法的时间复杂度是 O(n3)O(n^3)O(n3)(三个嵌套循环),会在数据量大时显著拖慢程序的执行速度。优化可以通过在一个循环中完成。

一种改进方案是使用 双指针法,将时间复杂度降至 O(n)O(n)O(n)。以下是优化后的代码 

from typing import List

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # 指针 j 记录非零元素的放置位置
        j = 0
        for i in range(len(nums)):
            # 如果 nums[i] 非零,则将其放在 j 指针的位置,j 向后移
            if nums[i] != 0:
                nums[j] = nums[i]
                j += 1
        
        # 将剩余的位置填充为 0
        for i in range(j, len(nums)):
            nums[i] = 0

 优化后的代码说明

  1. 第一个循环遍历数组,将非零元素按顺序移到数组的前部分,同时 j 指针记录下一个放置非零元素的位置。
  2. 第二个循环j 开始,将剩余位置全部设置为 0,确保所有 0 都移到末尾。
  3. 时间复杂度为 O(n)O(n)O(n),因为只需遍历数组一次,并在需要时移动非零元素或填充零。
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        # 获取数组的长度
        n = len(nums)
        # 初始化两个指针,left和right,分别指向非零元素的插入位置和当前遍历的位置
        left = right = 0
        # 使用while循环遍历数组
        while right < n:
            # 如果当前遍历到的元素不是0
            if nums[right] != 0:
                # 将非零元素与left指针指向的位置的元素交换
                nums[left], nums[right] = nums[right], nums[left]
                # 移动left指针到下一个位置,为下一个非零元素做准备
                left += 1
            # 无论当前元素是否为0,都移动right指针到下一个位置
            right += 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ws_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值