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;
}
}