颜色分类

GitHub跳转原题关系图返回列表

三指针荷兰国旗: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()

复杂度

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

总结

三路划分(荷兰国旗)的核心是三个区间的边界维护。遇到 2 交换后不推进 i,因为交换过来的值需要再判断。