数据结构与算法之 leetcode 数组颜色分类 荷兰国旗问题

数据结构与算法阿木 发布于 2025-07-12 5 次阅读


数组颜色分类(荷兰国旗问题)的代码实现与优化

数组颜色分类问题,也被称为荷兰国旗问题,是计算机科学中一个经典的问题。它要求我们根据某个特定的规则将数组中的元素进行重新排序,使得满足条件的元素排列在一起。这个问题在LeetCode上以“荷兰国旗问题”的形式出现,其难度为中等。

荷兰国旗问题通常以一个包含红、白、蓝三种颜色的数组为例,要求将数组中的红色元素放在最前面,白色元素放在中间,蓝色元素放在最后面。这个问题可以通过多种算法来解决,包括快速排序的分区操作、双指针法等。

问题分析

假设我们有一个包含红、白、蓝三种颜色的数组,我们可以用0、1、2分别代表红色、白色和蓝色。我们的目标是重新排列这个数组,使得所有0(红色)在数组的开始,所有2(蓝色)在数组的末尾,而所有1(白色)在中间。

解决方案

快速排序的分区操作

快速排序算法中的分区操作可以用来解决荷兰国旗问题。我们可以选择数组中的任意一个元素作为基准,然后将数组分为两部分:小于基准的元素和大于基准的元素。对于荷兰国旗问题,我们可以选择白色元素作为基准。

python

def partition(nums, low, high):


pivot = nums[low]


left = low


right = high


while True:


while nums[low] < pivot:


low += 1


while nums[right] > pivot:


right -= 1


if low >= right:


break


nums[low], nums[right] = nums[right], nums[low]


low += 1


right -= 1


nums[low], nums[high] = nums[high], nums[low]


return low

def sortColors(nums):


low, high = 0, len(nums) - 1


while low <= high:


pivot_index = partition(nums, low, high)


if pivot_index == 0:


low += 1


elif pivot_index == len(nums) - 1:


high -= 1


else:


sortColors(nums[:pivot_index])


sortColors(nums[pivot_index + 1:])

示例


nums = [2, 0, 2, 1, 1, 0]


sortColors(nums)


print(nums) 输出应为 [0, 0, 1, 1, 2, 2]


双指针法

双指针法是一种更直观的解法,它使用两个指针分别指向数组的开始和结束,然后根据当前指针指向的元素与目标颜色的比较结果来移动指针。

python

def sortColors(nums):


left, right = 0, len(nums) - 1


while left <= right:


if nums[left] == 0:


left += 1


elif nums[left] == 2:


nums[left], nums[right] = nums[right], nums[left]


right -= 1


else:


nums[left], nums[right] = nums[right], nums[left]


left += 1


right -= 1

示例


nums = [2, 0, 2, 1, 1, 0]


sortColors(nums)


print(nums) 输出应为 [0, 0, 1, 1, 2, 2]


代码优化

在上述两种方法中,双指针法通常比快速排序的分区操作更优,因为它不需要递归调用,从而减少了函数调用的开销。以下是双指针法的优化版本:

python

def sortColors(nums):


left, right = 0, len(nums) - 1


while left <= right:


while left <= right and nums[left] == 0:


left += 1


while left <= right and nums[right] == 2:


right -= 1


if left <= right:


nums[left], nums[right] = nums[right], nums[left]


left += 1


right -= 1

示例


nums = [2, 0, 2, 1, 1, 0]


sortColors(nums)


print(nums) 输出应为 [0, 0, 1, 1, 2, 2]


在这个优化版本中,我们分别跳过了所有已经正确放置的0和2,这样可以减少不必要的比较和交换操作。

总结

荷兰国旗问题是一个典型的算法问题,它不仅考察了我们对数组操作的理解,还考察了我们对算法效率的优化能力。通过快速排序的分区操作和双指针法,我们可以有效地解决这个问题。在实际应用中,选择哪种方法取决于具体场景和性能要求。