适合少量的非负数排序
思路
原数组值为下标,出现次数为值,生成新数组(a) 在将新数组(a)遍历,a下标为数组b的值,值为数b的push次数
「推导」
5,5,1,2,4,4,4,3
[_,1,1,1,3,2]
1,2,3push1次
4,push3次
5,push2次
[1,2,3,4,4,4,5,5]
「普通版」
function sortArray(nums: number[]): number[] {
let len = nums.length;
if (len === 1) {
return nums;
}
//这是遍历原数组生成的count数组
const count: (number | undefined)[] = [];
for (let i = 0; i < len; i++) {
//值作下标
const j = nums[i];
//判断该下标有没有值,如果有就++,没有就添加为1
if (count[j]) {
(count[j] as number)++;
} else {
count[j] = 1;
}
}
const arr:number[] = []
for(let i = 0;i<count.length;i++){
//push次数
let j = count[i]
if(typeof j === 'number'){
for(let k = 0;k<j;k++){
arr.push(i)
}
}
}
return arr;
}
「优化版 支持负数」
//假设,原数组长度为100,值为10~90,那么10之前和90之后的全是undfined,由此新数组【count】长度为 max-min+1
//当有负数时min值就往左移长度不够就加,newmin和oldmin之间就可以放负数
//[负数,min,....]
function sortArray1(nums: number[]): number[] {
let len = nums.length;
if (len === 1) {
return nums;
}
let min:number = nums[0]
let max:number = nums[0]
for(let i = 1;i<len;i++){
if(nums[i] < min){
min = nums[i]
}
if(nums[i] > max){
max = nums[i]
}
}
//这是遍历原数组生成的count数组
const count: (number | undefined)[] = new Array(max-min+1);
for (let i = 0; i < len; i++) {
//值作下标
const j = nums[i] - min;//相对下标
//判断该下标有没有值,如果有就++,没有就添加为1
if (count[j]) {
(count[j] as number)++;
} else {
count[j] = 1;
}
}
const arr:number[] = []
for(let i = 0;i<count.length;i++){
//push次数
let j = count[i]
if(typeof j === 'number'){
for(let k = 0;k<j;k++){
arr.push(i+min)//真实下标
}
}
}
return arr;
}
时间复杂度O(n+n+k) = O(n)
空间复杂度O(k)
未改变原先的顺序,稳定