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 时仍然有一个元素需要检查。

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

相关推荐
老师我太想进步了20261 小时前
【数据结构-4】算法美学之顺序表
数据结构·算法
风影同志783241 小时前
编码器是激活函数吗?—— 一个看起来很像、其实不是的类比
算法
UIU1141 小时前
P1481 魔族密码
c++·算法·动态规划
文丑颜不良啊2 小时前
LeetCode1961~1980题目解析
java·leetcode
文丑颜不良啊3 小时前
LeetCode2001~2020题目解析
java·leetcode
加宝的起点雷达5 小时前
40 条候选里 38 条来自同一个源,主卡整屏重样
人工智能·算法·创业
秋天的怀念_David5 小时前
算法一千零一夜 · 第二十六夜 协议的母语
java·spring boot·算法
文丑颜不良啊6 小时前
LeetCode2021~2040题目解析
java·leetcode