[LeetCode] Sort Colors [23]

题目

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?

原题链接(点我)

解题思路

一个数组,数组元素含有3种颜色,红,白,蓝。要求将数组排序,将相同颜色排在一起,整体按照红白蓝的顺序。
这个题在日常生活中很常见。比如要将东西归类,当然这个题简化成了相同颜色就认为完全相同。
基于这个特点,可以先统计各个颜色出现的次数,然后在按照题目要求的红白蓝的顺序,依次放n个红,m个白,k个蓝,就Okay了,代码详见代码一。这个思路也就是题目下面提示的方法,这个方法需遍历2次数组,本题要求遍历一次就搞定的方法,想想这个还是有点难度的。
这个题目其实我们很容易就能联想到快排的划分上来,但是仔细一想,如果按照划分来做达不到题目要求,比如你按照1来划分,一次划分的结果只能保证1后的元素都为2,但不能保证前面1和0之间的关系。
在此基础上可以继续拓展下,标准的划分是按照一个pivot来划分,这里我能不能指定2个pivot。假如指定2个pivot,一个是0,一个是2,那么分割后就有3段,一段是小于等于0,中间段大于0小于2,最后一段大于等于2。这个正好符合题意,也只需要遍历一次数组。代码详见代码二。

代码实现
代码一(计数)
class Solution {
public:
    void sortColors(int A[], int n) {
        if(A==NULL || n<=0) return;
        int count[3] = {0,0,0};
        for(int i=0; i<n; ++i)
            ++count[A[i]];
        int i=0, p=0;
        for(; i<count[0]; ++i, ++p)
            A[p]=0;
        for(i=0; i<count[1]; ++i, ++p)
            A[p] = 1;
        for(i=0; i<count[2]; ++i, ++p)
            A[p] = 2;
    }
};
代码二(划分)
class Solution {
public:
    void sortColors(int A[], int n) {
        if(A==NULL || n<=0) return;
        int p0=0, p2=n-1, p=0;
        while(p<n && p0<p2 && p<=p2){
            if(A[p] == 0){
                swap(A[p], A[p0]);
                ++p;
                ++p0;
            }else if(A[p] == 2){
                swap(A[p], A[p2]);
                --p2;
            }else
                ++p;
        }
    }
};

如果你觉得本篇对你有收获,请帮顶。
另外,我开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
你可以搜索公众号: swalge  或者扫描下方二维码关注我

(转载文章请注明出处: http://blog.csdn.net/swagle/article/details/29413827 )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值