给定一个包含红,白,蓝且长度为 n 的数组,将数组元素进行分类使相同颜色的元素相邻,并按照红、白、蓝的顺序进行排序。
我们可以使用整数 0,1 和 2 分别代表红,白,蓝。
注意事项
不能使用代码库中的排序函数来解决这个问题。
排序需要在原数组中进行。
样例
给你数组 [1, 0, 1, 2]
, 需要将该数组原地排序为 [0, 1, 1, 2]
。
挑战
一个相当直接的解决方案是使用计数排序扫描2遍的算法。
首先,迭代数组计算 0,1,2 出现的次数,然后依次用 0,1,2 出现的次数去覆盖数组。
你否能想出一个仅使用常数级额外空间复杂度且只扫描遍历一遍数组的算法?
比较容易联想到快排,把所有0扔到1左边,把所有2扔到1右边,问题就在于我们怎样找扔的位置
因为我们不知道1在哪,所以把0扔到最左(left),2扔到最右(right),初始化left=0,right=size()-1
2比较好处理,查到一个2就往最后right扔,扔一次就right--
那么怎么找0该扔到的位置?
有这么几种情况
1、i=left,就是说查到的0就在该在的位置,那么这时候需要i++,left++
2、i!=left,那么这时候就需要交换,交换后left位置为0,所以需要left++
1 void sortColors(vector<int> &nums) { 2 // write your code here 3 int left=0, right=nums.size()-1; 4 int index=0; 5 while(index<=right){ 6 if(nums[index]==0){ 7 if(index==left){ 8 index++; 9 } 10 else{ 11 swap(nums[index], nums[left]); 12 } 13 left++; 14 } 15 else if(nums[index]==2){ 16 swap(nums[index], nums[right]); 17 right--; 18 } 19 else{ 20 index++; 21 } 22 } 23 }
看的出来,查到1就直接跳过了,只处理查到0和2的情况