Solution 1: 2-pass+counting sort+3个extra space
类似与桶排序,先pass一遍,记下0,1,2的个数
然后重新对数组赋值
class Solution {
public void sortColors(int[] nums) {
int count1=0,count2=0,count0=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==0)count0++;
else if(nums[i]==1)count1++;
else count2++;
}
for(int i=0;i<count0;i++){
nums[i]=0;
}
for(int i=count0;i<count0+count1;i++){
nums[i]=1;
}
for(int i=count0+count1;i<nums.length;i++){
nums[i]=2;
}
}
}
Solution 2:1-pass+two pointers+twp extra spaces
思路:我们只要定下0,2的位子,那么1的位子也能定了
p指0,q指2。p走过的地方一定都是0,q走过的地方一定都是2。
i从头开始遍历,只要i=0,就和p交换,p++,p走到下一个0应该在的位子。只要i=2,就和q交换,q–,p走到下一个2应该在的位子。
为了避免[ 2, 0,2, 1,0]这种,p和i都指向第0个,q指向最后一个。第0个是2,所以和q交换,q–;此时i=0,i和p交换后,p++了,i还是0,就陷入while的无限循环中了。其实发现i<p,i位置就已经确定是0了。
同理[0,1,1,2]这种,p指0,q指最后一个数,期间q没有动,然后当i和q都最后一个2时,i和q进行swap,q–,i还是2,陷入无限while循环中。其实发现此时i>q了,i确定也是2了。
如果i < p,说明此时i处放的已经是0了,可以跳出while循环i继续遍历了。同理,如果i > q,说明此时i处放的已经是2了。
class Solution {
public void sortColors(int[] nums) {
int p=0;
int q=nums.length-1;
for(int i=0;i<nums.length;i++){
while(nums[i]==0||nums[i]==2){
//跳出while的循环条件
if(i<p||i>q) break;
if(nums[i]==0){
swap(nums,i,p);
p++;
}
else if(nums[i]==2){
swap(nums,i,q);
q--;
}
}
if(i>=q)break;
}
}
public void swap(int[] nums,int a,int b){
if(a==b)return ;
nums[a]^=nums[b];
nums[b]^=nums[a];
nums[a]^=nums[b];
return;
}
}
Solution 3:one-pass 牛逼
// one pass in place solution
void sortColors(int A[], int n) {
int n0 = -1, n1 = -1, n2 = -1;
for (int i = 0; i < n; ++i) {
if (A[i] == 0)
{
A[++n2] = 2; A[++n1] = 1; A[++n0] = 0;
}
else if (A[i] == 1)
{
A[++n2] = 2; A[++n1] = 1;
}
else if (A[i] == 2)
{
A[++n2] = 2;
}
}
}