要点
若待排序的数组取值范围并不太大,那么可以记录下每个元素的个数,然后再按顺序把元素写在答案数组中,即可完成排序。
把元素按序写入排序数组有两种写法,一种是从前往后写,简单快捷,但只适用于单元素数组排序。另一种写法需要统计cnt数组的前序和,首先从后往前记录下原数组位置i的元素在最终排序数组中的位置,记录在数组idx[i]中,这样可以排序 (key, value) 数组。
为了排序算法的稳定性,在找每个元素在排序数组中的位置时,从后往前遍历。
若有负值出现,可以为所有元素赋一个偏移值。
还可以发展成桶排序,基数排序。
步骤
1 . 统计原序列中每个值的出现次数,记为cnt数组。
2 . 从小到大枚举值的范围,对cnt数组求前缀和,记为sum数组。
3 . 从后往前枚举每个元素a[i],分配其在答案中的位置idx[i]为当前的sum[a[i]],也就是将其放在所有值等于a[i]中的最后一个。并且将sum[a[i]]减少1,保证下次再遍历到同样的值时,它分配的位置正好在idx[i]前面一个。
复杂度分析
时间复杂度 O ( n ) O(n) O(n), 空间复杂度 O ( n + k ) O(n + k)