返回

leetcode:颜色分类,荷兰国旗问题

前端

引言

leetcode 中的「颜色分类」问题,也称为「荷兰国旗问题」,给出了一个包含 0、1 和 2 三种元素的数组,要求将其重新排列,使所有 0 元素位于数组的开头,所有 1 元素位于中间,所有 2 元素位于末尾。本篇文章将提供两种不同的解决方案,并分析它们的优缺点。

解决方案一:单指针法

单指针法是一种简单直观的算法,它使用一个指针遍历数组,并根据元素的值将它们移动到正确的位置。以下是单指针法的步骤:

  1. 定义一个指针 i,指向数组的开头。
  2. 遍历数组,从开头到结尾。
  3. 如果当前元素为 0,将其与指向数组开头的指针 i 交换,然后将指针 i 向右移动一位。
  4. 如果当前元素为 2,将其与指向数组末尾的指针 j 交换,然后将指针 j 向左移动一位。
  5. 重复步骤 3 和步骤 4,直到遍历完整个数组。

以下是以单指针法实现的 Python 代码示例:

def sort_colors_one_pointer(nums):
    # 定义指针 i 和 j,指向数组的开头和结尾
    i = 0
    j = len(nums) - 1

    # 遍历数组,从开头到结尾
    while i <= j:
        # 如果当前元素为 0,将其与指向数组开头的指针 i 交换,然后将指针 i 向右移动一位
        if nums[i] == 0:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1

        # 如果当前元素为 2,将其与指向数组末尾的指针 j 交换,然后将指针 j 向左移动一位
        elif nums[i] == 2:
            nums[i], nums[j] = nums[j], nums[i]
            j -= 1

        # 如果当前元素为 1,则保持原位,继续遍历
        else:
            i += 1

    # 返回重新排列后的数组
    return nums

解决方案二:双指针法

双指针法是另一种解决「颜色分类」问题的算法,它使用两个指针,一个指针指向数组的开头,另一个指针指向数组的末尾。以下是双指针法的步骤:

  1. 定义两个指针,i 和 j,分别指向数组的开头和结尾。
  2. 遍历数组,从开头和结尾同时向中间移动。
  3. 如果当前元素为 0,将其与指向数组开头的指针 i 交换,然后将指针 i 向右移动一位。
  4. 如果当前元素为 2,将其与指向数组末尾的指针 j 交换,然后将指针 j 向左移动一位。
  5. 如果当前元素为 1,则保持原位,继续遍历。
  6. 当指针 i 和指针 j 相遇时,遍历结束。

以下是以双指针法实现的 Python 代码示例:

def sort_colors_two_pointers(nums):
    # 定义指针 i 和 j,指向数组的开头和结尾
    i = 0
    j = len(nums) - 1

    # 遍历数组,从开头和结尾同时向中间移动
    while i < j:
        # 如果当前元素为 0,将其与指向数组开头的指针 i 交换,然后将指针 i 向右移动一位
        if nums[i] == 0:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1

        # 如果当前元素为 2,将其与指向数组末尾的指针 j 交换,然后将指针 j 向左移动一位
        elif nums[i] == 2:
            nums[i], nums[j] = nums[j], nums[i]
            j -= 1

        # 如果当前元素为 1,则保持原位,继续遍历
        else:
            i += 1

    # 返回重新排列后的数组
    return nums

复杂度分析

对于单指针法和双指针法,它们的时间复杂度都是 O(n),其中 n 是数组的长度。这是因为这两种算法都遍历了整个数组一次。空间复杂度都是 O(1),因为它们不使用额外的空间来存储临时数据。

结论

本篇文章讨论了 leetcode 中的经典问题——颜色分类,也称为荷兰国旗问题。该问题要求将给定数组中的元素按特定顺序重新排列,使所有 0 元素位于数组的开头,所有 1 元素位于中间,所有 2 元素位于末尾。本文提供了两种不同的解决方案,并分析了它们的时间复杂度和空间复杂度,帮助读者更好地理解算法和编程技巧。