zoukankan      html  css  js  c++  java
  • [leetcode] 75. 分类颜色(常数空间且只扫描一次算法)

    75. 分类颜色

    我们直接按难度最高的要求做:你能想出一个仅使用常数空间的一趟扫描算法吗?

    1. 常数空间
    2. 只能扫描一趟。注意,是一趟,而不是O(n)

    题中只会出现3个数字:0,1,2。换句话说,0肯定在最前面,2肯定都在后面,1都在中间

    思路大概这样:

    我们用双指针法,i从前往后扫,当num[i]!=0时,j从后往前扫,直到找到第一个非2的数。然后我们就需要分情况讨论了

    当num[i]2 && num[j]0时,两数可以直接交换,i++然后继续
    当num[i]1 && num[j]0时,两数交换,然后此时i继续往前扫,找下一个非0的数。找到后还要分情况讨论,找到的如果是2,那太好了,就可以把num[j]上的1替换掉了。
    当num[i]2 && num[j]1时,balabala
    。。。

    总之,双指针法,如果找到了0或者2,那么其位置可以立即确定,直接替换到前面或者后面,替换的过程中呢,中间的1也就逐渐的确定位置了,当i>=j时,排序完成。整个算法只扫了一次数组,且只用的少量的空间

    class Solution {
        public void sortColors(int[] nums) {
            int i = 0;
            int j = nums.length - 1;
            while (i < j) {
                while (i < j && nums[i] == 0) i++;
                if (i >= j) break;
                if (nums[i] == 1) {
                    int k = i + 1;
                    while (k < j && nums[k] == 1) {
                        k++;
                    }
                    if (nums[k] == 0) {
                        nums[i] = 0;
                        nums[k] = 1;
                        i++;
                    } else if (k < j && nums[k] == 2) {
                        while (j > k && nums[j] == 2) {
                            j--;
                        }
                        if (nums[j] == 0) {
                            nums[j] = 2;
                            nums[i] = 0;
                            nums[k] = 1;
                            i++;
                        } else if (nums[j] == 1) {
                            nums[j] = 2;
                            nums[k] = 1;
                        }
                    } else break;
                } else if (nums[i] == 2) {
                    while (j > i && nums[j] == 2) {
                        j--;
                    }
                    if (nums[j] == 0) {
                        nums[i] = 0;
                        nums[j] = 2;
                        i++;
                    } else if (nums[j] == 1) {
                        nums[i] = 1;
                        nums[j] = 2;
                    }
                }
            }
        }
    }
    
  • 相关阅读:
    Linux内核中的红黑树
    研究UEVENT相关东西,看到2篇优秀的博文,转载与此
    Nor Nand OneNand
    Linux设备模型(总线、设备、驱动程序和类)
    linux驱动的入口函数module_init的加载和释放(转)
    hwclock(Linux)
    Linux块设备驱动
    pdflush内核线程池及其中隐含的竞争
    Nand Flash与Nor Flash
    linux内核I2C体系结构(注意结构体原型)
  • 原文地址:https://www.cnblogs.com/acbingo/p/9374808.html
Copyright © 2011-2022 走看看