一.问题:
在[a,b]区间,任取k个整数(可重复)并对所取的数列进行排序。如数列A: [4,9,10,10,5,4,5]
二.思路:
中心思想:以数列A中某一元素'9'为例,不大于他的数有5个,那么9应该排在第4位;存在相同元素的情况,如‘10’,此时,需要稍作修改。
三.步骤:
A:
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
A[i] | 4 | 9 | 10 | 10 | 5 | 4 | 5 |
B:统计区间内元素的个数
j | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Num1 | 2 | 2 | 0 | 0 | 0 | 1 | 2 |
C:数列A中小于等于i的元素个数
j | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Num2 | 2 | 4 | 4 | 4 | 4 | 5 | 7 |
1. 从A[0]开始归位,从C的num2看出,A[0]放在第1位
k | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
D[i] |
| 4 |
|
|
|
|
|
2. 归完位后,C中对应的Num2进行 减一;
j | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Num2 | 1 | 4 | 4 | 4 | 4 | 5 | 7 |
3. 重复
四.代码展示
public static void main(String[] args) {
int[] a = {6,6,5,5,4,4,3,3,2};
countSort(a);
}
private static void countSort(int[] a) {
int min2 = a[0];
int max2 = a[0];
//获得最大最小值
for (Integer i : a) {
if(i > max2){
max2 = i;
continue;
}
if(i <min2){
min2 = i;
}
}
//0->min2;
//2->min2+1;
//max2-min2->max2;
int[] b = new int[max2-min2+1];
//计数
for(int ai:a){
b[ai-min2]+=1;
}
//算小于等于某元素的个数
int[] c = new int[b.length];
c[0] = b[0];
for(int i=1;i<b.length;i++){
c[i] = b[i]+c[i-1];
}
System.out.println(Arrays.toString(c));
//归位
int[] d = new int[a.length];
//倒序遍历?貌似和正序仅有一点小区别
//a[0]=6,a[1]=6;d[7]=a[0],d[8]=a[1];
/*for(int i=a.length-1;i>=0;i--){
int k = a[i]-min2;
d[c[k]-1] = a[i];
c[k] -= 1;
}*/
//a[0]=6,a[1]=6;d[8]=a[0],d[7]=a[1];
for(int i=0;i<a.length;i++){
int k = a[i]-min2;
d[c[k]-1] = a[i];
c[k] -= 1;
}
System.out.println(Arrays.toString(d));
}