LeetCode 75 Sort Colors 颜色分类(荷兰国旗)

Given an array with n objects colored red, white or blue, sort them in-place 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.

Example:

Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]

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 a one-pass algorithm using only constant space?

解法1:

类似于:多名员工排序问题:http://blog.sina.com.cn/s/blog_13c6397540102wzv8.html

计数排序(区分桶排序)

两次循环

class Solution {
public:
    void sortColors(vector<int>& nums) 
    {
         int count[3] = {0}, idx = 0;
          for (int i = 0; i < nums.size(); ++i)
              ++count[nums[i]];
          for (int i = 0; i < 3; ++i) 
          {
              for (int j = 0; j < count[i]; ++j) 
              {
                nums[idx++] = i;
             }
        }
    }

};

解法2:

双指针实现

遍历一次数组。用两个指针分别指向首尾。遍历一次数组,遇到0时,将0向前搬移,遇到2时,向后搬移

class Solution {
public:
    void sortColors(vector<int>& nums) 
    {
      int left =0,right=nums.size()-1;
        for(int i=0;i<=right;++i)
        {
            if(nums[i]==0) 
                swap(nums[left++],nums[i]);
            else if(nums[i]==2) 
                swap(nums[right--],nums[i--]);
        }
    }
};

参考:https://blog.csdn.net/qq_43387999/article/details/86982438

解法3:

3路快速排序区分2路快排(普通快排),针对数组中有重复时。

快速排序的优化:https://www.cnblogs.com/2390624885a/p/7067669.html

class Solution {
public:
    void sortColors(vector<int>& nums) 
    {
     if(nums.empty())
            return;
        int zero = -1;          //[0,zero]元素为1
        int two = nums.size();  //[two,nums.size() - 1]元素为2

        for(int i = 0; i < two; )
        {
            if(nums[i] == 1)
                ++i;
            else if(nums[i] == 0)
                swap(nums[++zero],nums[i++]);
            else if(nums[i] == 2)
                swap(nums[--two],nums[i]);
        }
    }
};

另一种写法: 

/*
由于只有012 三个数为此选择1作为基准v
而通用的基准往往是放在第一个位置,并从第二个位置开始,所以结束后最后还要将基准v放到合适的位置
*/



class Solution {
public:
    void sortColors(vector<int>& nums) 
    {
     if(nums.empty())
            return;
        int i = 0;  // nums[0..<i) == 0
        int j = 0;  // nums[i..<j) == 1
        int k = nums.size(); // nums[k..<n) == 2
       //分为3步走
        while( j < k )//j表示当前元素所在的位置
        {
            if( nums[j] == 1 )
                j++;
            else if( nums[j] == 0 )
                swap( nums[i++] , nums[j++] );
            else{ // nums[j] == 2
                assert( nums[j] == 2 );//断言判断是否为2
                swap( nums[j] , nums[k-1] );
                k --;
            }
        }

        return;
    }
};

参考:【1】三路快排1 https://blog.csdn.net/my_clear_mind/article/details/81413869

【1】https://www.cnblogs.com/ariel-dreamland/p/9154279.html

【3】易于理解的三路排序https://www.douban.com/note/219642993/

【4】课程:https://www.imooc.com/article/16141

【5】3路排序讲解透彻 http://www.cnblogs.com/deng-tao/p/6536302.html 写的不错结合4一起理解

猜你喜欢

转载自blog.csdn.net/heda3/article/details/88264671