leetcode 75颜色分类

LeetCode 75. 颜色分类(双指针)

一、完整代码(精简注释)

复制代码
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int p = 0, q = nums.size() - 1;
        // p 左边全是 0,q 右边全是 2

        int i = 0; // 遍历指针
        while (i <= q) {
            if (nums[i] == 2) {
                swap(nums[i], nums[q]); // 将 2 放到右边
                q--; // i 不动,重新检查交换过来的元素
            }
            else if (nums[i] == 0) {
                swap(nums[i], nums[p]); // 将 0 放到左边
                p++;
                i++;
            }
            else {
                i++; // 遇到 1,直接跳过
            }
        }
    }
};

二、算法总结

1. 核心思想

采用双指针 + 遍历指针(三指针法),通过交换元素,将数组划分为三个区域:

  • 左边全部是 0。

  • 中间全部是 1。

  • 右边全部是 2。

不需要额外数组,只需遍历一次即可完成排序。

2. 指针定义

  • p:指向下一个应该存放 0 的位置。

  • q:指向下一个应该存放 2 的位置。

  • i:遍历数组,判断当前元素。

在遍历过程中,数组分为四个区域:

区域 含义
[0, p-1] 全部是 0
[p, i-1] 全部是 1
[i, q] 尚未处理的元素
[q+1, n-1] 全部是 2

3. 指针移动规则

情况一:遇到 0

复制代码
swap(nums[i], nums[p]);
p++;
i++;

将 0 交换到左边,p 和 i 同时右移。

情况二:遇到 1

复制代码
i++;

1 本来就应该位于中间,因此直接跳过。

情况三:遇到 2

复制代码
swap(nums[i], nums[q]);
q--;

将 2 交换到右边,q 左移,但 i 不移动。

原因:从右边交换过来的元素可能是 0、1 或 2,还没有检查过,所以需要继续判断当前位置。

4. 为什么循环条件是 i <= q?

复制代码
while (i <= q)

因为:

  • i 是未处理区域的起点。

  • q 是未处理区域的终点。

  • 当 i == q 时,还有最后一个元素需要处理。

  • 当 i > q 时,说明所有元素都已经处理完成。

因此循环条件必须是 i <= q。

5. 最终结果

假设原数组:

复制代码
nums = [2, 0, 2, 1, 1, 0]

排序完成:

复制代码
nums = [0, 0, 1, 1, 2, 2]

p = 2;
q = 3;
i = 4;

最终:

  • p 左边全部是 0。

  • q 右边全部是 2。

  • p 到 q 之间全部是 1(区间可能为空)。

6. 复杂度分析

时间复杂度:\(O(n)\)

每次循环至少使 i 右移或者 q 左移,因此总操作次数为 \(O(n)\)。

空间复杂度:\(O(1)\)

只使用了三个指针变量,没有额外申请数组。

三、重点记忆

这道题的核心就是三个指针的配合:

复制代码
遇到 0 → 和 p 交换 → p++,i++
遇到 1 → 直接跳过 → i++
遇到 2 → 和 q 交换 → q--,i 不动

最关键的两点:

  1. 遇到 2 时,i 不能移动,因为交换回来的元素还没有处理。

  2. 循环条件是 i <= q,因为 i == q 时仍然有一个元素需要检查。

记住这两个细节,就能掌握这道题的双指针解法。

相关推荐
Liaiyang661 小时前
空圈容错视角 · 多维切面篇:我们生活的世界,不止三维
人工智能·算法·系统架构·前沿技术·哲学·认知科学
闻缺陷则喜何志丹1 小时前
【环】P6709 [CCC 2020] Swapping Seats 环|普及+
算法·洛谷·环
开开心心就好1 小时前
打印机卡住打不了?一键清理卡死打印队列
服务器·开发语言·算法·pdf·ocr·idea·visual studio code
格物致胜工业数智技术1 小时前
锂电纠偏测量那些坑,明治ETD-0612激光纠偏传感器怎么填?
人工智能·算法
垆边人似月.2 小时前
带权区间调度,优先级可负
算法
重生之小比特2 小时前
【算法拾光】双指针|三数之和 + 四数之和
算法
我爱工作&工作love我2 小时前
P14359 [CSP-J 2025] 异或和
算法
茉莉玫瑰花茶2 小时前
GO [ 数据格式 ]
服务器·网络·算法·golang
小poop2 小时前
高级排序算法与性能对比——归并、非比较排序及总结
数据结构·算法·排序算法