题目:
给定一个有n个元素的数组,数组中元素的取值只有0,1,2三种可能。为这个数组排序。
方法一:
计数排序:分别统计0、1、2的元素个数。
方法一代码:
package com.haobi;
public class SortColors {
public static void main(String[] args) {
int[] arr = {0,1,2,0,2,1,0,2,1,2,2,1,0,1};
sortColors(arr);
for(int a : arr) {
System.out.print(a+" ");
}
}
public static void sortColors(int[] nums) {
int[] count = new int[3];
for(int i=0;i<nums.length;i++) {
//加入断言
assert(nums[i] >= 0 && nums[i] <= 2);
//题目保证了nums[i]一定是0、1、2
count[nums[i]]++;
}
int index = 0;
for(int i=0;i<count[0];i++) {
nums[index++] = 0;
}
for(int i=0;i<count[1];i++) {
nums[index++] = 1;
}
for(int i=0;i<count[2];i++) {
nums[index++] = 2;
}
}
}
方法二:
Java学习手册:(数据结构与算法-排序)三路快排
由于刚好有三个元素,可以采样三路快排的思想,对整个数组采取一次三路快拍。
时间复杂度:O(n)
空间复杂度:O(1)
方法二代码:
package com.haobi;
public class SortColors1 {
public static void main(String[] args) {
int[] arr = {0,1,2,0,2,1,0,2,1,2,2,1,0,1};
sortColors(arr);
for(int a : arr) {
System.out.print(a+" ");
}
}
public static void sortColors(int[] nums) {
int zero=-1;//nums[0...zero] == 0
int two = nums.length;//nums[two...n-1] == 2
int temp = 0;
for(int i=0;i<two;) {//直到i和two相遇
if(nums[i] == 1) {
i++;
}else if(nums[i] == 2) {
temp = nums[--two];
nums[two] = nums[i];
nums[i] = temp;
}else {//nums[i] == 0
assert(nums[i] == 0);
temp = nums[++zero];
nums[zero] = nums[i];
nums[i++] = temp;
}
}
}
}