给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
注:不使用排序算法,仅使用一遍遍历,和常数空间来进行分类
我的思路就是,记录1的最左边的位置和2的最左边的位置,然后每次向前遍历,只要遇到0,或者2就于刚才记录的位置进行置换;
这好像与荷兰国旗相似;我已经忘了荷兰国旗问题。
class Solution {
public:
void partition(vector<int>& nums)
{
int size = nums.size() - 1;
int lo = 0;
int hi = size;
int pos_1 = 0; //记录1的最左边
int pos_2 = hi; //记录2的最左边的前一个
int check = 0;
while( lo <= pos_2 )
{
if( nums[lo] == 1)
{
if(check == 0) pos_1 = lo; //记录第一次1的最左边
check = 1;
++lo;
}
else if(nums[lo] == 2)
{
swap(nums[lo], nums[pos_2]); //将2换到后面
pos_2--;
}
else
{
if(pos_1 == lo) //这两个值相等,说明此时pos_1的位置是0
lo++;
else
swap(nums[pos_1], nums[lo]); //否则将1的最左边和0换
pos_1++; //更新pos_1的位置
}
}
}
void sortColors(vector<int>& nums) {
partition(nums);
}
};
下面是精简版:
class Solution {
public:
void sortColors(vector<int>& nums) {
int l=0, r=nums.size()-1;
for(int i=0; i<=r; ++i){
if(nums[i]==0) swap(nums[l++], nums[i]);
if(nums[i]==2) swap(nums[r--], nums[i--]);
}
}
};