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]
用3个数字表示3种颜色,0,1,2分别代表红白蓝
让按0,1,2的顺序给数组排序
思路1:
count sort
因为数字种类少,所以记录下每种出现的次数,然后重新给数组赋值
简陋易懂版代码:
public void sortColors(int[] nums) {
if (nums == null || nums.length == 0) {
return;
}
int count0 = 0;
int count1 = 0;
int n = nums.length;
for(int i = 0; i < n; i++) {
if(nums[i] == 0) {
count0 ++;
} else if(nums[i] == 1) {
count1 ++;
}
}
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 < n; i++) {
nums[i] = 2;
}
}
精简版
public void sortColors(int[] nums) {
if (nums == null || nums.length == 0) {
return;
}
int[] color = new int[3];
int n = nums.length;
for(int i = 0; i < n; i++) {
color[nums[i]] ++;
}
for(int i = 0, cur = 0; i < 3; i++) {
for(int j = 0; j < color[i]; j++) {
nums[cur++] = i;
}
}
}
思路2:
交换法,遇到0向左交换,遇到2向右交换,遇到1 pass
定义双指针,red指针指向左边,交换一次右移一步,blue指针指向右边,交换一次左移一步
需要注意的是遍历数组的i 指针是和red同起点的,i 遇到2必然会交换到右边blue指向的地方,所以red指针只可能指向0或1,那么当i 在后面遇到0时和red处的值交换,只可能交换过来0或1,所以交换完后i直接走向下一步
但是i指向2,和blue交换时,可能交换过来的是0或2,这时下一步仍需要交换,所以和blue交换完时i 还要停留在原位置直到不是0或2为止
public void sortColors(int[] nums) {
if (nums == null || nums.length == 0) {
return;
}
int n = nums.length;
int red = 0;
int blue = n - 1;
int i = 0;
//注意这里是<=,防止出现由2交换到0后blue--,导致没有交换完0直接退出的情况
while(i <= blue) {
if(nums[i] == 0) {
//swap
int tmp = nums[i];
nums[i] = nums[red];
nums[red] = tmp;
i ++;
red ++;
} else if (nums[i] == 2) {
//swap
int tmp = nums[i];
nums[i] = nums[blue];
nums[blue] = tmp;
blue --;
} else {
i ++;
}
}
}