随笔 - 0,  文章 - 900,  评论 - 0,  阅读 - 33万

Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note:
You are not suppose to use the library's sort function for this problem.

click to show follow up.

Follow up:
A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's.

Could you come up with an one-pass algorithm using only constant space?

 

 

原题链接: http://oj.leetcode.com/problems/sort-colors/ 
这道题也是数组操作的题目,其实就是要将数组排序,只是知道数组中只有三个元素0,1,2。熟悉计数排序的朋友可能很快就发现这其实就是使用计数排序,元素空间只需要三个元素即可。代码如下: 

  1. public void sortColors(int[] A) {  
  2.     if(A==null || A.length==0)  
  3.         return;  
  4.     int[] res = new int[A.length];  
  5.     int[] helper = new int[3];  
  6.     for(int i=0;i<A.length;i++)  
  7.     {  
  8.         helper[A[i]]++;  
  9.     }  
  10.     for(int i=1;i<3;i++)  
  11.     {  
  12.         helper[i]=helper[i]+helper[i-1];  
  13.     }  
  14.     for(int i=A.length-1;i>=0;i--)  
  15.     {  
  16.         res[helper[A[i]]-1] = A[i];  
  17.         helper[A[i]]--;  
  18.     }  
  19.     for(int i=0;i<A.length;i++)  
  20.     {  
  21.         A[i] = res[i];  
  22.     }  
  23. }  

上面的代码是计数排序的标准解法,可以看到总共进行了三次扫描,其实最后一次只是把结果数组复制到原数组而已,如果不需要in-place的结果只需要两次扫描。
其 实就算返回元素组也可以是两次扫描,这需要用到元素只有0,1,2的本质。我们知道helper[i]中是包含着0,1,2的元素数量,我们只需要按照 helper[0,1,2]的数量依次赋值过来即可(每层循环把helper[i]--,如果helper[i]到0就i++就可以了),只是这样就不是 计数排序比较标准的解法,我希望还是复习一下。
这种方法的时间复杂度是O(2*n),空间是O(k),k是颜色的数量,这里是3。
上 述方法需要两次扫描,我们考虑怎么用一次扫描来解决。其实还是利用了颜色是三种这一点,道理其实也简单,就是搞两个指针,一个指在当前0的最后一个下标, 另一个是指在当前1的最后一个下标(2不需要指针因为剩下的都是2了)。进行一次扫描,如果遇到0就两个指针都前进一步并进行赋值,如果遇到1就后一个指 针前进一步并赋值。代码如下: 

  1. public void sortColors(int[] A) {  
  2.     if(A==null || A.length==0)  
  3.         return;  
  4.     int idx0 = 0;  
  5.     int idx1 = 0;  
  6.     for(int i=0;i<A.length;i++)  
  7.     {  
  8.         if(A[i]==0)  
  9.         {  
  10.             A[i] = 2;  
  11.             A[idx1++] = 1;  
  12.             A[idx0++] = 0;  
  13.         }  
  14.         else if(A[i]==1)  
  15.         {  
  16.             A[i] = 2;  
  17.             A[idx1++] = 1;  
  18.         }  
  19.     }  
  20. }  

上述方法时间复杂度还是O(n),只是只需要一次扫描,空间上是O(1)(如果颜色种类是已知的话)。
这道题我觉得主要还是熟悉一下计数排序计数排序是线性排序中比较重要的一种,关于排序要搞个专题专门的复习一下,很多排序的基本思想都对解题有帮助哈。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
    void sortColors(int A[], int n) {
        if(NULL == A || n < 1) return;
        int index0 = 0;
        int index1 = 0;
        for(int i = 0;i < n;++i)
        {
            if(A[i] == 0)
            {
                A[i] = 2;
                A[index1++] = 1;
                A[index0++] = 0;
            }
            else if(A[i] == 1)
            {
                A[i] = 2;
                A[index1++] = 1;
            }
        }
    }
};

 

posted on   风云逸  阅读(100)  评论(0)    收藏  举报
(评论功能已被禁用)
编辑推荐:
· 大数据高并发核心场景实战,数据持久化之冷热分离
· 运维排查 | SaltStack 远程命令执行中文乱码问题
· Java线程池详解:高效并发编程的核心利器
· 从“看懂世界”到“改造世界”:AI发展的四个阶段你了解了吗?
· 协程本质是函数加状态机——零基础深入浅出 C++20 协程
阅读排行:
· .NET 8 gRPC 实现高效100G大文件断点续传工具
· STM32学会要花费多长时间?一个从机械转行老程序员的血泪史
· LinqPad:C#代码测试学习一品神器
· .NET入行第4年(第二集)
· C#/.NET/.NET Core技术前沿周刊 | 第 43 期(2025年6.16-6.22)
< 2025年6月 >
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5
6 7 8 9 10 11 12

点击右上角即可分享
微信分享提示