【leetcode 数组】Sort Colors

<span style="font-size: 18px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">题目</span>

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.

题目大意就是将数组按0,1,2的顺序排好,如{0,1,2,2,1,1,0,0,2}排成{0,0,0,1,1,1,2,2,2}
方法有很多种,one pass的,two pass的,直接调用库函数解决的,详见下面代码及分析

#方法一

最简单的方法,就是先遍历一轮,统计0、1、2的个数,然后遍历第二轮,置相应个数的0、1、2。
class Solution {  
public:  
    void sortColors(int A[], int n) {  
        int count[3]={0,0,0};  
        for(int i=0;i<n;i++)  
          count[A[i]]++;  
        int i=0;  
        while(count[0]--) A[i++]=0;  
        while(count[1]--) A[i++]=1;  
        while(count[2]--) A[i++]=2;  
    }  
};


#方法二

题目要求是one pass
下面也不是严格的one pass
<span style="font-size:18px;">class Solution {
public:
/*
双指针,i指向头,j指向尾
当A[i]等于0,i++
当A[i]等于1,则置为0,并且记录1的个数的num加一
当A[i]等于2,则swap(A[i],A[j]),这样确保j处的元素是2,然后j--
循环这个过程,直到i==j跳出循环
此时还需判断A[j]是否为0,如果不为0,则该位的元素不用管,还是其原来的数(1或者2),然后从j-1处,开始往后置num个1
*/
    void sortColors(int A[], int n) {
        int i=0,j=n-1,num=0;
        while(i<j)
        {
            if(A[i]==0) i++;
            else if(A[i]==1)  { num++;A[i]=0; i++;}
            else  {int tmp=A[j];A[j]=A[i];A[i]=tmp;j--;}
        }
        if(A[j]!=0)  j--;
        while(num--) A[j--]=1;
    }
};</span>

#方法三

one pass

设置下标red=0,blue=n-1

遍历一轮,发现0则与A[red]交换,red++,i++;发现2则与A[blue]交换,blue--

<span style="font-size:18px;">class Solution {
public:
    void sortColors(int A[], int n) {
        int red=0,blue=n-1;
        for(int i=0;i<blue+1;)
        {
            if(A[i]==0) swap(A[i++],A[red++]);  //交换过后,A[i]肯定不是2,因为2肯定已经被交换到后面。只能是0或者1,可以不用管,直接i++
            else if(A[i]==2) swap(A[i],A[blue--]);
            else i++;
        }
    }
};
</span>

#方法四

调用库函数,快速排序的partition(),先按0分割,再按1分割
<span style="font-size:18px;">class Solution {
public:
    void sortColors(int A[], int n) {
      partition( partition(A,A+n,bind1st(equal_to<int>(),0)),A+n,bind1st(equal_to<int>(),1));
    }
};</span>






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值