创见博客
颜色分类
七崽爱吃小饼干2026/02/10阅读 0

颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:

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

示例 2:

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

提示:

  • n == nums.length
  • 1 <= n <= 300
  • nums[i] 为 0、1 或 2

解法

解法一:单指针
ts
/**
 Do not return anything, modify nums in-place instead.
 */
function sortColors(nums: number[]): void {
    // 颜色分类和一般的排序不太一样,只有三种数字
    // 所以只需要把0放到左边,2放到右边即可
    const n = nums.length
    // 如果只用一个指针,则需要两趟遍历,一次把0放到头部,一次把1放到中间
    // 第一次遍历,处理0
    let p = 0
    for(let i = 0; i < n; i++){
        if(nums[i] === 0){
            let tmp = nums[p]
            nums[p] = nums[i]
            nums[i] = tmp 
            p++
        }
    }
    // 第二次遍历,处理1
    for(let i = p; i < n; i++){
        if(nums[i] === 1){
            let tmp = nums[p]
            nums[p] = nums[i]
            nums[i] = tmp 
            p++
        }
    }
};
解法二:双指针
ts
/**
 Do not return anything, modify nums in-place instead.
 */
function sortColors(nums: number[]): void {
    // 颜色分类和一般的排序不太一样,只有三种数字
    // 所以只需要把0放到左边,2放到右边即可
    const n = nums.length
    // 双指针法只需要一次遍历
    let p0 = 0, p1 = 0 // p0负责交换0,p1负责交换1
    for(let i = 0; i < n; i++){
        if(nums[i] === 1){ // 如果碰到1就直接交换
            [nums[i], nums[p1]] = [nums[p1], nums[i]]
            p1++
        }else if(nums[i] === 0){
            [nums[i], nums[p0]] = [nums[p0], nums[i]]
            if(p0 < p1){ // 这种情况下会把1换走,所以要把1换回给p1
                [nums[i], nums[p1]] = [nums[p1], nums[i]]
            }
            p0++
            p1++
        }
    }
};
评论
0/100