Evan Wang
Evan WangFrontEnd Developer
  • Evan Wang
    Evan WangFrontEnd Developer
  • 前端相关
  • 算法题
  • 日常笔记
  • Chat With AI

两数之和
两数相加
无重复字符的最长子串
最长回文子串
盛水最多的容器
三数之和
电话号码的字母组合
有效括号
合并两个有序链表
括号生成
下一个排列
搜索旋转排序数组
在排序数组中查找元素的第一个和最后一个位置
删除链表的倒数第n个节点
组合总和
全排列
旋转图像
字母异位词分组
最大子数组合
跳跃游戏
反转链表
反转链表2
合并区间
最小路径和
编辑距离
颜色分类
爬楼梯
组合
子集
不同的二叉搜索树
验证二叉搜索树
对称二叉树
二叉树的层序遍历
二叉树的最大深度
从前序与中序遍历序列构造二叉树
只出现一次的数字
二叉树展开为链表
最长连续序列
单词拆分
环形链表
环形链表2
排序链表
相交链表
乘积最大子数组
最小栈
多数元素
打家劫舍
数组中重复的数据
二叉树的中序遍历
卖股票的最佳时机
数组中的第K个最大元素

  1. Articles
  1. More
  2. 26-颜色分类.mdx
目录
题目思路代码
1093 字
约 3 分钟
更新于 2026/08/20

颜色分类

题目

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]

示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]

思路

方法一:
冒泡排序,将数据按从小到大排序,(重点:题目要求在原数组上修改)

方法二:
三指针: 题目要求将 0 放在前面,2 放在后面,1 放在中间。 那么声明left,right 两个指针,遍历数组,每次将当前元素和 0 或者 2 做比较

  • 如果当前元素等于 0 ,则将当前元素换到 left 指针所指的位置,同时 left++
  • 如果当前元素等于2, 则将当前元素换到 right 指针所指的位置,同时 right--,
    • 且当前循环的下标 i 需要左移一个位置,因为换完位置后,当前 arr[i] 还没有和 0 或者 2 进行比较。

注意: for 循环的第二个条件,循环下标 i 需要小于等于右指针 right,因为 right 右边的元素已经符合题目要求。

代码:

// 方法一:
const sortColors1 = (nums) => {
    for (let i = 0; i < nums.length; i++) {
        for (let j = 0; j < nums.length - 1- i; j++) {
            if (nums[j] > nums[j + 1]) {
                [nums[j], nums[j + 1]] = [nums[j + 1], nums[j]]
            }
        }
    }
    return nums
}
 
 
 
// 方法二:
const sortColors2 = (nums) => {
    let left = 0,
        right = nums.length - 1;
 
    for (let i = 0; i <= right; i++) {
        if (nums[i] === 0) {
            [nums[left], nums[i]] = [nums[i], nums[left]]
            left  = left + 1;
        } else if (nums[i] === 2) {
            [nums[right], nums[i]] = [nums[i], nums[right]]
            right = right - 1
            i = i - 1; // 这里 i-1 是因为换完为止后,当前位置的元素没有进行比较。
        }
    }
    return nums
}