题目:
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.
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?
class Solution {
public:
void sortColors(vector<int>& nums) {
if(nums.empty()) return;
int cnt[3] = {0};
for(int i = 0; i < nums.size(); ++i){
switch(nums[i]){
case 0: cnt[0]++; break;
case 1: cnt[1]++; break;
// case 2: cnt[2]++; break;
default:break;
}
}
for(int i = 0; i < nums.size(); ++i){
if(i < cnt[0]) nums[i] = 0;
else if(i < cnt[0]+cnt[1]) nums[i] = 1;
else nums[i] = 2;
}
}
};
方法二:运用双指针,只遍历一遍
class Solution {
public:
void sortColors(vector<int>& nums) {
if (nums.empty()) return;
int next0 = 0;//next0指向下一存放0的位置
int next2 = nums.size() - 1;//next2指向下一个存放2的位置
while (next0 < nums.size() && nums[next0] == 0) ++next0;//初始化next0为从头到尾第一个不为0的位置
while (next2 >= 0 && nums[next2] == 2) --next2;//初始化next2为从尾到头第一个不为2的位置
int i = next0;//i用于遍历数组,指向0或2
while (i <= next2){
if (nums[i] == 1){//遇到1,不处理,继续向前
++i;
continue;
}
if (nums[i] == 0){//遇到0,将该位置元素与next0元素交换
swap(nums[i], nums[next0]);
}
else{//遇到2,将该位置元素与next2元素交换
swap(nums[i], nums[next2]);
}
//next0所指一定是1,但是next2所指元素可能是1也可能是0,所以每次交换之后都要更新next2, next0和i(由于next2是next0的循环终止条件,所以先更新next2,因为i值得更新依赖于next0,所以i最后更新)
while (next2 >= 0 && nums[next2] == 2) --next2;
while (next0 <= next2 && nums[next0] == 0) ++next0;
i = next0>i ? next0 : i;//i一定在next0的前面或相等
}
}
};