LeetCode-075:颜色分类,荷兰国旗问题就是三段区间不变量
本题在线练习:LeetCode 75. 颜色分类 — 在线练习(免费 · 无需登录 · AI 辅助)(https://onefly.top/zero2Leetcode/playground.html?id=75)
配套刷题网站 Zero2Leetcode — 内置本地 OJ + AI 教练,零门槛开始刷 Hot 100。
题目概述
给定只包含 0,1,2 的数组 nums,原地排序,使相同颜色相邻,并按照 0,1,2 顺序排列。
要求原地,通常也希望一次遍历完成。
核心思路:维护三个区间(荷兰国旗)
用三个指针 p0, i, p2 维护不变量:
[0, p0)全是0[p0, i)全是1(p2, n-1]全是2[i, p2]是未知区域,靠i去扫描处理
当 nums[i]:
- 等于
0:与p0交换,p0 += 1,i += 1 - 等于
1:i += 1 - 等于
2:与p2交换,p2 -= 1,但i不动(因为换过来的元素还没判断)
代码实现(Python,可直接提交)
from typing import List
class Solution:
def sortColors(self, nums: List[int]) -> None:
p0 = 0
i = 0
p2 = len(nums) - 1
while i <= p2:
if nums[i] == 0:
nums[p0], nums[i] = nums[i], nums[p0]
p0 += 1
i += 1
elif nums[i] == 1:
i += 1
else:
nums[p2], nums[i] = nums[i], nums[p2]
p2 -= 1
逐行拆解:为什么遇到 2 时 i 不能加?
因为 nums[i] 和 nums[p2] 交换后,i 位置来了一个“未知元素”,可能是 0、1 或 2。
如果这时 i += 1,就会跳过它,导致区间不变量被破坏。
手动模拟(nums=[2,0,2,1,1,0])
初始:p0=0,i=0,p2=5
- i=0 是 2:和 p2 交换 ->
[0,0,2,1,1,2], p2=4, i 仍为 0 - i=0 是 0:和 p0 交换(同位)->
[0,0,2,1,1,2], p0=1,i=1 - i=1 是 0:交换 ->
[0,0,2,1,1,2], p0=2,i=2 - i=2 是 2:和 p2 交换 ->
[0,0,1,1,2,2], p2=3, i=2 - i=2 是 1:i=3
- i=3 是 1:i=4 结束
复杂度分析
- 时间复杂度:
O(n),一次扫描 - 空间复杂度:
O(1),原地
总结
这题的价值在于建立“区间不变量”思维:
- 指针不是随便移动的,每一步都在维护三段已经确定的区域
- 交换不是为了排序本身,而是为了把元素扔进它应该属于的区间
把三段区间写清楚,代码就会自然且不容易错。

浙公网安备 33010602011771号