力扣第七十五题-颜色分类

174 阅读3分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

前言

力扣第七十五题 颜色分类 如下所示:

给定一个包含红色、白色和蓝色,一共 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]

进阶:

  • 你可以不使用代码库中的排序函数来解决这道题吗?
  • 你能想出一个仅使用常数空间的一趟扫描算法吗?

一、思路

这一题题目意思比较简单,就是将数组中的0 1 2 按升序排列

如果不考虑到一趟扫描的话,我们可以先遍历一遍数组,记下 0 1 2 的个数,再根据它们的个数来修改原来的数组即可。伪代码如下所示:

public void sortColors(int[] nums) {
    int zeroCnt = oneCnt = twoCnt = 0;
    // 遍历并计数
    for (i=0; i<nums.len; i++) {
        if(nums[i] == 0)
            zeroCnt++;
        else if(nums[i] == 1)
            oneCnt++;
        else twoCnt++;
    }
    // 原地修改
    for (i=0; i<nums.len; i++) {
        if(zeroCnt > 0) {
            nums[i] = 0;
            zeroCnt--;
        } else if(oneCnt > 0){
            nums[i] = 1;
            oneCnt--;
        } else{
            nums[i] = 2;
            twoCnt--;
        }
    }
}

既然要一趟遍历就完成排序的处理,我们不妨使用两个变量 p0p1 来存储最后一个 01 的位置

在遍历数组的时候,有如下三种情况

  1. 碰到0:交换 nums[i] 和 nums[++p0]。如果交换后 p1 > p0 说明交换的是 1,再将 nums[++p1]nums[i] 交换(不要让连续的 1 断开)
  2. 碰到1:如果 p1 < p0,则将 p1 = po(保证 10 的后面)。再 交换 nums[i] 和 nums[++p1]
  3. 碰到2:不做任何处理

举个例子

此处以 nums = [2,0,2,1,1,0] 作为例子

  1. 初始化变量 p0 = p1 = -1
  2. 遍历数组,nums[0] == 2 不做任何处理
  3. nums[1] == 0,交换 nums[0] 和 nums[1],数组变成 [0,2,2,1,1,0]p0 = 1
  4. nums[2] == 0nums[2] == 2 不做任何处理
  5. nums[3] == 1,此时 p1 < p0 则将 p1 = p0 = 0,再交换 nums[1] 和 nums[3],数组变成 [0,1,2,2,1,0]
  6. nums[4] == 1,交换 nums[2] 和 nums[4],数组变成 [0,1,1,2,2,0]
  7. nums[5] == 0,交换 nums[1] 和 nums[5],数组变成 [0,0,1,2,2,1]。再将移动后面的 1 补到连续 1 的后面即可。数组变为 [0,0,1,1,2,2]

二、实现

实现代码

实现代码与思路中保持一致

    public void sortColors(int[] nums) {
        int len = nums.length;
        int p0 = -1, p1 = -1;
        for (int i = 0; i < len; i++) {
            if (nums[i] == 0) { // 碰到0就交换
                nums[i] = nums[++p0];
                nums[p0] = 0;
                // 如果交换过来的是 1
                if (p0 <= p1) {
                    // 将交换过来的1移到1的最后面
                        nums[i] = nums[++p1];
                    nums[p1] = 1;
                }
            } else if (nums[i] == 1) {
                if (p1 < p0)
                    p1 = p0;
                nums[i] = nums[++p1];
                nums[p1] = 1;
            }
        }
    }

测试代码

    public static void main(String[] args) {
        int[] nums = {2,0,2,1,1,0};
        new Number75().sortColors(nums);
        System.out.println(nums);
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~