[路飞]_leetcode刷题_75. 颜色分类

153 阅读2分钟

题目

75. 颜色分类

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

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

示例 1:

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

示例 2:

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

示例 3:

输入:nums = [0]
输出:[0]

示例 4:

输入:nums = [1]
输出:[1]

解法

思路

双指针,遍历两遍。

  1. 第一遍,先处理0,从前往后遍历,遇到0则将其与p0位置元素交换,然后将p0往后移动一位。p0开始是0,这样能够继续保证p0左边的元素都是0。
  2. 第二遍,处理2,从后往前遍历,遇到2则将其与p2位置元素交换,然后将p2往前移动一位。p2开始是len-1,这样能够继续保证p2右边的元素都是2

处理完之后就能做到0都在左边的区间,2都在右边的区间,1都在中间

代码如下

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var sortColors = function(nums) {
    let len = nums.length;
    let p0 = 0;
    // [0,p0),保证这个区间内都是0
    // [p0,i],保证这个区间内都是1
    // (p2,len-1],保证这个区间内都是2
    for(let i=0;i<len;i++){
       if(nums[i]==0){
           nums[i] = nums[p0]
           nums[p0] = 0;
           p0++;
       }
    }
    let p2 = len-1
    for(let i=p2 ;i>=0;i--){
        if(nums[i]==2){
            nums[i] = nums[p2];
            nums[p2] = 2;
            p2--;
        }
    }
    return nums;
};

解法二

思路

双指针,遍历一遍。

上面的解法我们遍历了两遍,其实我们可以只遍历一遍就解决问题。

代码如下

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var sortColors = function(nums) {
    let len = nums.length;
    let p0 = 0;
    let p2 = len-1;
    // 定义指针含义如下
    // [0,p0) 都是0
    // [p0,i) 都是1
    // (p2,len-1] 都是2
    // 以上区间未包含[i,p2],这个区间的元素我们需要通过遍历去判断,所以跳出循环条件为i>p2
    for(let i=0;i<=p2;){
        if(nums[i] == 2){
            nums[i] = nums[p2];
            nums[p2] = 2;
            // 将2换到当前位置后,我们不能将i++,因为我们需要确定换过来的元素是多少
            p2--;
        }else if(nums[i] == 0){
            nums[i] = nums[p0];
            nums[p0] = 0;
            p0++;
            i++
        }else{
            // 如果当前元素是1,什么也不用干,下标往后走即可
            i++
        }
    }
    return nums;
};