• 颜色分类(LintCode) .


    颜色分类

    给定一个包含红,白,蓝且长度为n的数组,将数组元素进行分类使相同颜色的元素相邻,并按照红、白、蓝的顺序进行排序。

    我们可以使用整数0,1和2分别代表红,白,蓝。

    样例
     
    注意

    不能使用代码库中的排序函数来解决这个问题

    说明

    一个相当直接的解决方案是使用计数排序扫描2遍的算法。

    首先,迭代数组计算0,1,2出现的次数,然后依次用0,1,2出现的次数去覆盖数组。

    你否能想出一个仅使用常数级额外空间复杂度且只扫描遍历一遍数组的算法?

    代码写的乱糟糟的,难得写了注释。

    想法就是把0交换至左边,2交换至右边。

     1 class Solution {
     2     //总耗时: 14896 ms
     3     
     4     /**
     5      * @param nums: A list of integer which is 0, 1 or 2 
     6      * @return: nothing
     7      */
     8     public void sortColors(int[] nums) {
     9         int low = 0;
    10         int high = nums.length-1;
    11         //先找到最左的非0和最右的非2
    12         while(nums[low] == 0 && low < high) low++;
    13         while(nums[high] == 2 && low < high) high--;
    14 
    15         while(nums[low] == 2 || nums[high] == 0 && low < high) {
    16             //如果最左非0是2或者最右非2是0,则将其换至右边或左边
    17             if(nums[low] == 2) {
    18                 if(nums[high] == 0) {
    19                     nums[low++] = 0;
    20                     nums[high--] = 2;
    21                 }else {
    22                     nums[high--] = 2;
    23                     nums[low] = 1;
    24                 }
    25             }else {
    26                 if(nums[high] == 0) {
    27                     nums[low++] = 0;
    28                     nums[high] = 1;
    29                 }
    30             }
    31             //找到最左的非0和最右的非2
    32             while(nums[low] == 0 && low < high) low++;
    33             while(nums[high] == 2 && low < high) high--;
    34         }
    35         
    36         for(int i=low+1;i<high && low < high;i++) {
    37             //此时最左非0和最右非2都是1,用i找到0或2,交换到左端或右端
    38             if(nums[i] == 0) {
    39                 nums[low++] = 0;
    40                 nums[i] = 1;
    41             }else {
    42                 if(nums[i] == 2) {
    43                     nums[high--] = 2;
    44                     nums[i] = 1;
    45                 }
    46             }
    47             
    48             //找到最左的非0和最右的非2
    49             while(nums[low] == 0 && low < high) low++;
    50             while(nums[high] == 2 && low < high) high--;
    51             
    52             while(nums[low] == 2 || nums[high] == 0 && low < high) {
    53                 //如果最左非0是2或者最右非2是0,则将其换至右边或左边
    54                 if(nums[low] == 2) {
    55                     if(nums[high] == 0) {
    56                         nums[low++] = 0;
    57                         nums[high--] = 2;
    58                     }else {
    59                         nums[high--] = 2;
    60                         nums[low] = 1;
    61                     }
    62                 }else {
    63                     if(nums[high] == 0) {
    64                         nums[low++] = 0;
    65                         nums[high] = 1;
    66                     }
    67                 }
    68                 //找到最左的非0和最右的非2
    69                 while(nums[low] == 0 && low < high) low++;
    70                 while(nums[high] == 2 && low < high) high--;
    71             }
    72             //若此时的low>=i,显然要重新设置i
    73             if(i <= low) i = low+1;
    74         }
    75         //当上面的循环结束时,分类就已完成,只遍历了一次nums,辅助空间为常数
    76     }
    77 }
    View Code
  • 相关阅读:
    redis持久化,主从及数据备份
    验证redis的快照和AOF
    Erlang中日志管理
    erlang tcp发包速度测试
    树(234树插入查找显示)
    JDBC(初步试用)
    树(二叉树的插入删除查找遍历)
    哈希表(链地址法插入删除)
    哈希表-再哈希法插入删除
    哈希表-线性探测插入删除
  • 原文地址:https://www.cnblogs.com/FJH1994/p/5025769.html
Copyright © 2020-2023  润新知