返回

移动零:零被放逐的技巧

前端

移动零算法可以分为两类:

  • 双指针算法
  • 交换算法

双指针算法

双指针算法是解决移动零问题的最简单的方法之一。它使用两个指针来遍历数组。第一个指针指向当前位置,第二个指针指向数组末尾。当第一个指针遇到 0 时,它将第二个指针向左移动,直到第二个指针指向非零元素。然后,它将第一个指针和第二个指针指向的元素进行交换。这个过程重复进行,直到第一个指针遍历完整个数组。

def move_zeros(nums):
  """
  Move all 0s to the end of the array.

  Args:
    nums: The array to move the 0s in.

  Returns:
    The array with all 0s moved to the end.
  """

  # Initialize the two pointers.
  i = 0
  j = len(nums) - 1

  # While the first pointer is less than or equal to the second pointer.
  while i <= j:
    # If the element at the first pointer is 0.
    if nums[i] == 0:
      # Move the second pointer to the left until it points to a non-zero element.
      while j > i and nums[j] == 0:
        j -= 1

      # If the second pointer is still greater than or equal to the first pointer.
      if j >= i:
        # Swap the elements at the first and second pointers.
        nums[i], nums[j] = nums[j], nums[i]

      # Move the second pointer to the left.
      j -= 1

    # Move the first pointer to the right.
    i += 1

  # Return the array.
  return nums

双指针算法的时间复杂度是 O(n),其中 n 是数组的长度。空间复杂度是 O(1),因为该算法不需要额外空间。

交换算法

交换算法是解决移动零问题的另一种方法。它通过交换数组中的元素来移动 0。该算法首先将数组中的第一个非零元素与第一个 0 元素进行交换。然后,它将数组中的第二个非零元素与第二个 0 元素进行交换,以此类推。这个过程重复进行,直到数组中的所有 0 元素都被交换到数组的末尾。

def move_zeros(nums):
  """
  Move all 0s to the end of the array.

  Args:
    nums: The array to move the 0s in.

  Returns:
    The array with all 0s moved to the end.
  """

  # Initialize the index of the first non-zero element.
  i = 0

  # Iterate over the array.
  for j in range(len(nums)):
    # If the element at the current index is non-zero.
    if nums[j] != 0:
      # Swap the elements at the current index and the first non-zero index.
      nums[i], nums[j] = nums[j], nums[i]

      # Increment the index of the first non-zero element.
      i += 1

  # Return the array.
  return nums

交换算法的时间复杂度是 O(n^2),其中 n 是数组的长度。空间复杂度是 O(1),因为该算法不需要额外空间。

比较

双指针算法和交换算法都是解决移动零问题的有效方法。双指针算法的时间复杂度更低,但交换算法的空间复杂度更低。在实际应用中,我们应该根据具体情况选择合适的方法。

结论

移动零算法是解决 LeetCode 283. 移动零题目的经典算法。它要求我们编写一个函数,将给定数组中的所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。这道题目既考验了程序员的基本功,也考验了他们对算法的理解。在本文中,我们介绍了两种不同的方法来解决这道题目,并分析了每种方法的优缺点。希望通过这篇文章,你能更好地理解移动零算法的原理,并能够灵活地应用这些算法来解决实际问题。