算法小知识-----04.20-----颜色分类

104 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情

周三都来了,周末还远吗

颜色分类

该题出自力扣的75题 —— 颜色分类【中等题】,有时候题意并不难,之所以为中等题是因为需要复杂度的提升

审题

image.png

  • 该题的题意相对简单,就是给出一个整型数组,数组内存放着0/1/2 ,三种数,需要排列数组,使之按0、1、2的书序排列,并且不能使用库的sort(Arrays.sort())
  • 需要注意的是,题意还需要使用常数空间复杂度 + 一趟的遍历(时间复杂度O(n))
  • 三数的排列
    • 解法一:双指针
      • 给定两个初始变量,left和right
      • while循环双指针数组
      • 如果右指针当前为2则左移,如果左指针当前为0则右移
      • 如果数组的左指针 > 右指针则 左指针 与右指针的对调,并且左指针右移 + 右指针左移
      • 双指针,因为顾及了0和2,最后中间的必定为1。
      • 时间复杂度为O(n),虽然在左右指针内存在while循环,但是并不影响只是一趟
      • 空间复制度O(1)
    • 解法二:三指针
      • 给定3个指针分别指向边界,对应着0、1、2三个数的下标
      • 循环数组,每次遍历到的值依次移动指针
        • 如果为0,则代表3指针同时后移
        • 如果为1,则代表1和2指针的后移
        • 如果为2,则代表指针2 后移
      • 3指针的巧妙之处在于,3个指针同时指向边界,根据遇到的值而右移指针。在移动指针的同时,根据顺序去覆盖,也就是位置的调换
      • 与该题解相似的可以在数组上重建,节省空间

编码

class Solution {
    public void sortColors(int[] nums) {
        int num0 = 0,num1 = 0,num2 = 0;
        for (int i =0;i<nums.length;i++){
            int num = nums[i];
            if (num == 0){
                nums[num2++] = 2;
                nums[num1++] = 1;
                nums[num0++] = 0;
            }else if (num == 1){
                nums[num2++] = 2;
                nums[num1++] = 1;
            }else {
                nums[num2++] = 2;
            }
        }
    }
}

image.png