📌  相关文章
📜  Python3程序将所有零移动到数组末尾| Set-2(使用单次遍历)(1)

📅  最后修改于: 2023-12-03 15:04:19.687000             🧑  作者: Mango

Python3程序将所有零移动到数组末尾| Set-2(使用单次遍历)

本文主要介绍如何使用Python3编写程序将所有零移动到数组末尾,使用单次遍历的方法。

问题描述

给定一个整数数组,写一个 Python3 函数,将所有零移动到它们的末尾,并保持其余的元素的顺序不变。例如:

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

注意:

  • 必须在原地修改输入数组,使用O(1)额外空间并尽可能完美地使用已有的数组空间;
  • 尽管考虑所有元素,但并非所有元素都需要被移动;事实上,只有不是零的元素才应该受到保护。
解决方案

使用单次遍历的方法,可以在 O(n) 的时间复杂度内完成问题解决,且能够达到空间复杂度 O(1) 的要求。

具体做法是,通过两个指针 i 和 j,分别指向队列头和尾,每次遍历数组时,将非零元素移到数组 i 指针的位置,同时右移 i 指针。当遍历结束后,从 i 指针位置开始,将剩余的长度都填充为零。

Python3 代码实现如下:

def moveZeroes(nums):
    left, right = 0, len(nums) - 1
    while left < right:
        if nums[left] == 0:
            for j in range(left, right):
                nums[j], nums[j+1] = nums[j+1], nums[j]
            right -= 1
        else:
            left += 1
    for i in range(left, len(nums)):
        nums[i] = 0

其中,leftright 分别记录队列头和尾的位置,nums[left] 表示队列头的元素,nums[right] 表示队列尾的元素。当队列头元素为 0 时,通过循环将其从数组中移动到队列尾。最后,将从队列头到已移动元素位置(即 left)之间的元素都赋值为零即可。

此外,在实际应用中,为了减小时间复杂度,可以将需判断的元素缩小为非零元素,减少循环次数。如果数组中含有大量 0 元素,使用该方法能够显著提高程序性能。代码实现如下:

def moveZeroes2(nums):
    left, right = 0, len(nums) - 1
    while left < right:
        if nums[left] != 0:
            left += 1
        else:
            for j in range(left, right):
                if nums[j] != 0:
                    nums[left], nums[j] = nums[j], nums[left]
                    left += 1
                    break
            else:
                break

其中,判断位置 i 所代表元素是否为零,可以直接使用 Python 取反运算 not,更加简洁。同时,使用 for-else 结构能够显著提高执行效率,当循环结束后直接退出循环,避免不必要的判断。

总结

以上两种方法可以分别解决数组中所有零移动到数组末尾的问题,使用单次遍历实现算法时间复杂度为 O(n),同时空间复杂度为 O(1),符合题目要求。其中,缩小查找范围的方法,在数组包含大量零元素时,使用效果更优。