题目
题目描述
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]
提示:
n == nums.length
1 <= n <= 300
nums[i] 为 0、1 或 2
进阶:
你能想出一个仅使用常数空间的一趟扫描算法吗?
题解
思路分析
这个问题可以通过多种方法来解决,但最高效的方法是使用荷兰国旗问题(Dutch National Flag Problem)的解决方案,也称为三向切分快速排序(Three-way Partitioning Quick Sort)。这种方法只需要一次遍历数组,并且只使用常数级别的额外空间。
荷兰国旗问题算法步骤
-
初始化指针:
low指针指向数组的起始位置。mid指针同样指向数组的起始位置。high指针指向数组的末尾。
-
遍历数组:
- 当
mid小于等于high时,检查nums[mid]的值:- 如果
nums[mid] == 0,交换nums[low]和nums[mid],然后同时将low和mid向前移动一位。 - 如果
nums[mid] == 1,只需将mid向前移动一位。 - 如果
nums[mid] == 2,交换nums[mid]和nums[high],然后将high向后移动一位,但不要移动mid,因为交换过来的元素还需要检查。
- 如果
- 当
-
结束条件:
- 当
mid超过high时,排序完成。
- 当
这种方法确保了所有 0 都被移到数组的前面,所有 2 都被移到数组的后面,而所有 1 自然位于中间。
Python 实现代码
def sortColors(nums):
low, mid, high = 0, 0, len(nums) - 1
while mid <= high:
if nums[mid] == 0:
nums[low], nums[mid] = nums[mid], nums[low]
low += 1
mid += 1
elif nums[mid] == 1:
mid += 1
else: # nums[mid] == 2
nums[mid], nums[high] = nums[high], nums[mid]
high -= 1
代码解释
- 初始化指针:
low、mid和high分别初始化为数组的起始位置、起始位置和末尾位置。 - 遍历数组:通过
while循环遍历数组,根据nums[mid]的值执行不同的操作:- 如果
nums[mid] == 0,则与low指针所指元素交换,并同时移动low和mid指针。 - 如果
nums[mid] == 1,则仅移动mid指针。 - 如果
nums[mid] == 2,则与high指针所指元素交换,并仅移动high指针。
- 如果
- 结束条件:当
mid超过high时,排序完成。
这种方法的时间复杂度为 O(n),其中 n 是数组的长度,因为我们只遍历了一次数组。空间复杂度为 O(1),因为我们只使用了常数级别的额外空间。
提交结果



被折叠的 条评论
为什么被折叠?



