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;
}
};