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一起理解