zoukankan      html  css  js  c++  java
  • 颜色分类(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
  • 相关阅读:
    Canvas技术
    线段树树状数组小结
    html5 Canvas元素
    ccpc网络邀请赛部分
    2020杭电多校
    JavaFx 绘制图形和文本(笔记)
    P4094 [HEOI2016/TJOI2016]字符串(二分+多种数据结构)
    L3-021 神坛 (30分) (计算几何最小三角形面积)
    10月28日G、H、I题
    出栈序列的合法性 (25分) 之树状数组玄学做法
  • 原文地址:https://www.cnblogs.com/FJH1994/p/5025769.html
Copyright © 2011-2022 走看看