题目:Sort Colors
一个一维数组只有三个元素要把它排序。
思路1:快速排序。
后面专门总结这个排序算法。
思路2:计数排序。
例如:2 5 3 0 2 3 0 3的数组,先申请长度为6的数组,初始值为0.
然后统计其中0-5的每个数字的个数,
在按照大小顺序输出每个数字统计的次数,即排好序了。
初始:2 5 3 0 2 3 0 3 统计数组:0 0 0 0 0 0
第1次:2 5 3 0 2 3 0 3 统计数组:0 0 1 0 0 0
第2次:2 5 3 0 2 3 0 3 统计数组:0 0 1 0 0 1
第3次:2 5 3 0 2 3 0 3 统计数组:0 0 1 1 0 1
第4次:2 5 3 0 2 3 0 3 统计数组:1 0 1 1 0 1
第5次:2 5 3 0 2 3 0 3 统计数组:1 0 2 1 0 1
第6次:2 5 3 0 2 3 0 3 统计数组:1 0 2 2 0 1
第7次:2 5 3 0 2 3 0 3 统计数组:2 0 2 2 0 1
第8次:2 5 3 0 2 3 0 3 统计数组:2 0 2 3 0 1
最后:0 0 2 2 3 3 3 5
通过统计待排序元素的个数来排序;
它有诸多限制:
1.需要空间O(max-min);
2.需要元素为int或类似如此能再O(1)的复杂度上找到该元素对应的统计值。
package com.example.medium; /** * 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? * @author FuPing * */ public class SortColors { /** * 对值只有0/1/2的数组排序,可以用计数排序,时间复杂度O(n) * @param nums */ public void sortColors(int[] nums) { int i,sum0 = 0,sum1 = 0;//统计0、1的个数 for(i = 0;i < nums.length;i++){ if(nums[i] == 0)sum0++; else if(nums[i] == 1)sum1++; } for(i = 0;i < sum0;i++){ nums[i] = 0; } for(;i < sum1 + sum0;i++){ nums[i] = 1; } for(;i < nums.length;i++){ nums[i] = 2; } } /** * 对值只有三个范围的数组排序,可以用快速排序,时间复杂度O(n) * @param nums */ public void sortColors2(int[] nums) { int left = 0,right = nums.length - 1,middle = 0; for (int i : nums) {//找到2的元素的个数 if(i > 1)middle++; } middle = right - middle;//1从尾部减去2的个数的位置开始 while(left <= middle){ if(nums[right] > 1){//尾部大于1 right--; continue; } if(nums[middle] == 1){//中间等于1 middle--; continue; } //此时右边的数必定不是2的数,中间的数必定不是1 if(nums[left] > 1){//左边大于1 int temp = nums[right];//和右边交换 nums[right--] = nums[left]; nums[left] = temp; }else if(nums[left] == 1){//和中间交换 int temp = nums[middle]; nums[middle--] = nums[left]; nums[left] = temp; }else{ left++; } } } public static void main(String[] args) { // TODO Auto-generated method stub long startTime = System.currentTimeMillis(); int nums[] = {2,0}; new SortColors().sortColors2(nums); for (int i = 0; i < nums.length; i++) { System.out.print(nums[i] + " "); } System.out.println(); long endTime = System.currentTimeMillis(); System.out.println("程序运行时间:"+(endTime-startTime) + "ms"); } }