题目及测试
package pid075;
/*颜色分类
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
进阶:
一个直观的解决方案是使用计数排序的两趟扫描算法。
首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
你能想出一个仅使用常数空间的一趟扫描算法吗?
*/
public class main {
public static void main(String[] args) {
int[] testTable = {2,0,2,1,1,0};
test(testTable);
}
private static void test(int[] ito) {
Solution solution = new Solution();
int rtn;
long begin = System.currentTimeMillis();
System.out.println("ito=");
for(int i=0;i<ito.length;i++){
System.out.print(ito[i]+" ");
}
System.out.println();
solution.sortColors(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn=");
for(int i=0;i<ito.length;i++){
System.out.print(ito[i]+" ");
}
System.out.println();
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,1ms,很快)
用的是题目中的一次扫描个数,二次重写数组的方法,没想出来一次扫描排序
package pid075;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Solution {
public void sortColors(int[] nums) {
int length=nums.length;
if(length==0||length==1){
return;
}
int[] num=new int[3];
for(int i=0;i<length;i++){
int now=nums[i];
num[now]++;
}
for(int i=0;i<num[0];i++){
nums[i]=0;
}
for(int i=num[0];i<num[0]+num[1];i++){
nums[i]=1;
}
for(int i=num[0]+num[1];i<length;i++){
nums[i]=2;
}
return;
}
}
解法2(成功,0ms,极快)
如果只能扫一遍,很容易想到的就是左边存放0,右边存放2. 中间放1。
设置两个index,index0记录下一个0的位置,index0左边为0,index2记录下一个2的位置,index2右边为2.
然后使用i从头到尾扫一遍,直到与index2相遇。
i遇到0就换到左边去,遇到2就换到右边去,遇到1就跳过。
需要注意的是:由于index0记录第一个1的位置,因此A[index0]与A[i]交换后,A[index0]为0,A[i]为1,因此i++;
而index2记录第一个非2的位置,可能为0或1,因此A[index2]与A[i]交换后,A[index2]为2,A[i]为0或1,i不能前进,要后续判断。
由此该数组分为4段:[0,index0)-->0; [index0,i)-->1; [i,index2]-->乱序; (index2,n-1]-->2
0 0 0 1 1 1 2 1 0 2 1 2 2 2
^ ^ ^
index0 i index2
public void sortColors(int[] nums) {
if(nums.length==0||nums.length==1){
return;
}
int index0=0;
int index2=nums.length-1;
for(int i=0;i<=index2;){
int now=nums[i];
if(now==0){
swap(nums, i, index0);
index0++;
i++;
continue;
}
if(now==2){
swap(nums, i, index2);
index2--;
continue;
}
if(now==1){
i++;
continue;
}
}
return;
}
public void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}