Given an array with n objects colored red, white or blue, sort them 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.
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 an one-pass algorithm using only constant space?
Solution:Two pointers
思路a: literally two pass, 一次处理0,一次处理1
思路b:既然已经是two pass了,可以先在第一个pass count 012各自数量,提前直到他们在结果的范围,然后三指针放,或者可以直接填充012.
思路c(recommended): One Pass: if 0 和左边swap,if 2 和右边swap,1 不变
Time Complexity: O(N) Space Complexity: O(1)
Solution2:Two pointers 自Round1
Time Complexity: O(N) Space Complexity: O(1)
Solution_a Code:
class Solution {
public void sortColors(int[] nums) {
//swap all 0 to the left
int start = 0, end = nums.length - 1;
while(start < end) {
while(start < end && nums[start] == 0) start++;
while(start < end && nums[end] != 0) end--;
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
start++;
end --;
}
//swap all 1 to the left(after all 0)
start = 0;
end = nums.length - 1;
while(start < end) {
while(start < end && nums[start] < 2) start++;
while(start < end && nums[end] != 1) end--;
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
start++;
end --;
}
}
}
Solution_b Code:
public void sortColors(int[] nums) {
// 2-pass
int count0 = 0, count1 = 0, count2 = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {count0++;}
if (nums[i] == 1) {count1++;}
if (nums[i] == 2) {count2++;}
}
for(int i = 0; i < nums.length; i++) {
if (i < count0) {nums[i] = 0;}
else if (i < count0 + count1) {nums[i] = 1;}
else {nums[i] = 2;}
}
}
Solution_c Code:
class Solution {
public void sortColors(int[] nums) {
int zero = 0, two = nums.length - 1;
for (int i = 0; i <= two; i++) {
if (nums[i] == 0) {
// no need to skip 0 at zero, becuase that has already been taken care of ahead
swap(nums, i, nums, zero++);
}
else if(nums[i] == 2) {
//while(two > i && nums[two] == 2) two--; // optional skipping 2 at two backwards to speed up?
swap(nums, i--, nums, two--); // i-- is important here, example 1has been switch here, need to be evaluated again
}
}
}
private void swap(int[] A, int i, int[] B, int j) {
int tmp = A[i];
A[i] = B[j];
B[j] = tmp;
}
}
Solution2 Round1 Code:
class Solution {
public void sortColors(int[] nums) {
// sort 0
int index0 = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == 0) {
swap(nums, index0++, i);
}
}
// sort 1
int index1 = index0;
for(int i = index0; i < nums.length; i++) {
if(nums[i] == 1) {
swap(nums, index1++, i);
}
}
}
private void swap(int nums[], int x, int y) {
int tmp = nums[x];
nums[x] = nums[y];
nums[y] = tmp;
}
}