一组随机排列的字母数组。请编写一个时间复杂度为O(n)的算法,使得这些字母按照字母从小到大顺序排好。
说明:字母区分大小写,相同的字母,排序后小写排在大写前。
例如:R,B,B,b,W,W,B,R,B,w
排序为:b,B,B,B,B,R,R,w,W,W
1)描述思路(2分)
2)请用你熟悉的编程语言编码实现(8分)
解答:
1)把字母转映射为数字,然后用计数排序算法排序,得到的排序后再映射回原来的字母。
2)
/***
* 计数排序算法实现
* @author haward
* 时间复杂度:O(N)
*/
public class CountSort {
public static void countSort(int[] arr)
{
if(arr==null||arr.length==0)
return;
int max=max(arr);
int[] count=new int[max+1];
Arrays.fill(count, 0);
//计数
for(int i=0;i<arr.length;i++)
{
count[arr[i]]++;
}
int k=0;
for(int i=0;i<=max;i++)
{
for(int j=0;j<count[i];j++)
{
arr[k++]=i;
}
}
}
public static int max(int[] arr) {
int max=Integer.MIN_VALUE;
for(int ele:arr)
{
if(ele>max)
{
max=ele;
}
}
return max;
}
}
@org.junit.Test
public void testcountSort()
{
int[] arr={'R','B','B','b','W','W','B','R','B','w'};
//将每个元素乘以2
for(int i=0;i<arr.length;i++)
{
arr[i]*=2;
}
//arr[i]-=65的目的是把小写字母插入到大写字母的排列中
for(int i=0;i<arr.length;i++)
{
if(arr[i]>='a'*2&&arr[i]<='z'*2)
{
arr[i]-=65;//32.5*2
}
}
//计数排序
CountSort.countSort(arr);
//对排序后的元素还原
for(int i=0;i<arr.length;i++)
{
if(arr[i]%2==0)
{
arr[i]/=2;
}else{
arr[i]=(arr[i]+65)/2;
}
}
for(int i=0;i<arr.length;i++)
{
System.out.print((char)arr[i]);
}
}