三指针荷兰国旗:p0 指向 0 的右界,p2 指向 2 的左界,扫描指针交换后分类推进。
OJ: leetcodecn
题目 ID: sort-colors
难度:普及+/提高
标签:双指针排序
日期: 2026-07-29 13:02
题意
只含 0、1、2 的数组,一趟扫描原地排序。
思路
荷兰国旗问题:p0 指向已放好的 0 的右界,p2 指向已放好的 2 的左界,i 扫描。遇到 0 与 p0 交换并推进两者;遇到 2 与 p2 交换但只推进 p2(交换过来的可能是 0,需要再处理)。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
void sortColors(vector<int> &nums) {
int l = 0, m = 0, r = nums.size() - 1;
while (m <= r) {
if (nums[m] == 0)
swap(nums[l++], nums[m++]);
else if (nums[m] == 1)
m++;
else
swap(nums[m], nums[r--]);
}
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
for (int &x : a)
cin >> x;
Solution().sortColors(a);
for (int x : a)
cout << x << ' ';
return 0;
}python
#!/usr/bin/env python3
from typing import List
class Solution:
def sortColors(self, nums: List[int]) -> None:
l = m = 0
r = len(nums) - 1
while m <= r:
if nums[m] == 0:
nums[l], nums[m] = nums[m], nums[l]
l += 1
m += 1
elif nums[m] == 1:
m += 1
else:
nums[m], nums[r] = nums[r], nums[m]
r -= 1
def main():
n = int(input())
a = list(map(int, input().split()))
Solution().sortColors(a)
print(*a)
if __name__ == "__main__":
main()复杂度
- 时间复杂度:
。 - 空间复杂度:
。
总结
三路划分(荷兰国旗)的核心是三个区间的边界维护。遇到 2 交换后不推进 i,因为交换过来的值需要再判断。