1 中文题目
给定一个包含红色、白色和蓝色、共 n
个元素的数组 nums
,原地
对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
使用整数 0
、 1
和 2
分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题
示例:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
输入:nums = [2,0,1]
输出:[0,1,2]
提示:
- n = = n u m s . l e n g t h n == nums.length n==nums.length
- 1 ≤ n ≤ 300 1 \leq n \leq 300 1≤n≤300
nums[i]
为0
、1
或2
2 求解方法:三指针
2.1 方法思路
方法核心
使用三指针对数组进行一次遍历,left
指针左侧都是0
,right
指针右侧都是2
,中间区域都是1
,通过不断交换元素并移动指针,最终完成数组的原地排序,这种方法只需要一次遍历就能完成排序,且不需要额外空间。
实现步骤
(1)初始化阶段
- 设置三个指针:
- left:指向0的右边界
- right:指向2的左边界
- curr:当前处理的位置
- 所有指针初始位置设置
(2)遍历处理阶段
- 处理当前元素(nums[curr]):
- 如果是0:与left位置交换,left和curr都右移
- 如果是2:与right位置交换,right左移,curr不动
- 如果是1:curr右移
- 维护区域特性:
- [0, left):全是0
- [left, curr):全是1
- (right, n-1]:全是2
- [curr, right]:待处理区域
(3)终止条件
- 当curr超过right时停止
- 此时数组已经完成分类排序
方法示例
以 nums = [2,0,2,1,1,0]
为例:
初始状态:
nums = [2,0,2,1,1,0]
left = 0, curr = 0, right = 5
第一步:nums[curr] = 2
交换nums[curr]和nums[right]
nums = [0,0,2,1,1,2]
right = 4
第二步:nums[curr] = 0
交换nums[curr]和nums[left]
nums = [0,0,2,1,1,2]
left = 1, curr = 1
第三步:nums[curr] = 0
交换nums[curr]和nums[left]
nums = [0,0,2,1,1,2]
left = 2, curr = 2
第四步:nums[curr] = 2
交换nums[curr]和nums[right]
nums = [0,0,1,1,2,2]
right = 3
第五步:nums[curr] = 1
curr右移
nums = [0,0,1,1,2,2]
curr = 3
第六步:nums[curr] = 1
curr右移
nums = [0,0,1,1,2,2]
curr = 4
结束:curr > right,排序完成
2.2 Python代码
class Solution:
def sortColors(self, nums: list[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# 使用三个指针进行排序
# left指向0的右边界(下一个0应该放置的位置)
# right指向2的左边界(下一个2应该放置的位置)
# curr是当前处理的位置
left = curr = 0
right = len(nums) - 1
# 当curr指针没有超过right指针时继续处理
while curr <= right:
if nums[curr] == 0:
# 遇到0时,将其与left位置的数交换
# left和curr都向右移动
nums[left], nums[curr] = nums[curr], nums[left]
left += 1
curr += 1
elif nums[curr] == 2:
# 遇到2时,将其与right位置的数交换
# right向左移动,curr不移动(因为交换来的数还需要处理)
nums[right], nums[curr] = nums[curr], nums[right]
right -= 1
else:
# 遇到1时,不需要交换,curr直接向右移动
curr += 1
2.3 复杂度分析
- 时间复杂度:O(n),n是数组的长度
- 只需要一次遍历
- 每个元素最多被交换一次
- 所有操作都是常数时间
- 空间复杂度:O(1)
- 只使用了三个指针变量
- 所有操作都是原地进行
3 题目总结
题目难度:中等
数据结构:数组
应用算法:三指针