给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
进阶:
- 一个直观的解决方案是使用计数排序的两趟扫描算法。 首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
- 你能想出一个仅使用常数空间的一趟扫描算法吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-colors
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
完整代码
知道要借助快排的思想,但是没能实现。
这里设置三个指针:
- p0指向最后一个0位置(0的最右边界)的下一个位置,初始时p0=0
- p2指向最前一个2位置(2的最左边界)的前一个位置,初始时p2=nums.size()-1
- cur当前指针,初始时cur=0
在遍历当前序列的过程中
- 如果当前元素是0,将该元素和p0指示的元素交换,p0右移,cur右移
- 如果当前元素是2,将该元素和p2知识的元素交换,p2左移
- 如果当前元素是1,cur右移
说明:在上述指针移动的过程中有个容易有疑问的地方,为什么当前元素是0,交换后cur右移?
解释:cur指示的元素已经扫描需要继续处理下一个,但当当前元素是2的时候,交换后的元素还未处理,所以当前指针不能移动
class Solution {
public:
void sortColors(vector<int>& nums) {
//借助快排的思想,不过要有些改变
if(nums.size() < 2)
return;
int p0 = 0, p2 = nums.size() - 1, cur = 0;
//p0指向最后一个0位置的下一个位置,p2指向最后一个2位置的前一个位置,cur是当前位置
while(cur <= p2){
if(nums[cur] == 0){
nums[cur] = nums[p0];
nums[p0++] = 0;
++cur;
}
else if(nums[cur] == 2){
nums[cur] = nums[p2];
nums[p2--] = 2;
}
else
++cur;
}
}
};