问题描述
Given an array with n objects colored red, white or blue, sort them in-place 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.
Example:
Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
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 a one-pass algorithm using only constant space?
java实现
way1:使用计数的两阶段算法
循环记录个数,然后依次写入到nums数组中,如 [2,0,2,1,1,0]先循环得出有2个0, 2个1,2个2,然后向数组nums中依次写入2个0, 2个1,2个2
class Solution {
public static void sortColors(int[] nums) {
int[] count = new int[3];
for(int num : nums)
count[num]++;
/*
等价于
for (int i=0;i<nums.length;i++){
if(nums[i]==0)
count[0]+=1;
if(nums[i]==1)
count[1]+=1;
if(nums[i]==2)
count[2]+=1;
}
*/
int index=0;//count索引
int i=0;
int num=count[index];//count中元素的值
while (i<nums.length){
if(num!=0) {//num不为0,代表count中索引为index的值在nums中存在 比如index=0 num=1代表有一个0
nums[i] = index;//写入nums数组
i++;//nums指针后移
num--;//个数减一
}
if (num==0 && index+1 < 3) {//个数减到0 且索引未到2
index+=1;//count索引加一 开始写下一个数字
num = count[index];//num为当前索引下的值 也是nums列表中数值为index的数字的个数
}
}
}
}
way2 不适用计数的单阶段算法
设两个指针red 在开头,blue在最后。
遇到red 0交换,把0放到最左边去;遇到blue 2交换,把2都放到最右边去;white 1会被保留在中间。
red 0交换完毕不需要停留i位置原因是换回来的只可能是1,对于1不需要做任何处理,直接进入下次循环。
注意
1.当把blue2交换完毕之后,需要i–再进入for循环时候i++使得i位置不变,因为还需要继续检查被blue 2交换回来的数字
2.for循环结束条件是位置blue 因为blue位置以后的是blue 2
class Solution {
public static void sortColors(int[] nums) {
int red=0;
int blue=nums.length-1;
for(int i=0;i<=blue;i++){
if(nums[i]==0){
//swap
int temp=0;
temp=nums[red];
nums[red]=nums[i];
nums[i]=temp;
red++;
}
else if(nums[i]==2){
//swap
int temp=0;
temp=nums[blue];
nums[blue]=nums[i];
nums[i]=temp;
blue--;
i--;
}
}
}
}