一直误觉得写文章太耗费费时间,昨日为尊敬高贵帅气逼人的导师所一语惊醒(未一举成名之日,毫不提尊师名讳,嗯,没错),分享才是程序员最快的提高; 今天开始,作不到多写多练,就不是诚实善良的南方小菜啦程序员
不废话,直接进入主题算法
桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工做的原理是将数组分到有限数量的桶里。每一个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),最后依次把各个桶中的记录列出来记获得有序序列。桶排序是鸽巢排序的一种概括结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并非比较排序,他不受到O(n log n)下限的影响。数组
算法稳定性:假定在待排序的记录序列中,存在多个具备相同的关键字的记录,若通过排序,这些记录的相对次序保持不变,即在原序列中,A1=A2,且A1在A2以前,而在排序后的序列中A1仍在A2以前,则称这种排序算法是稳定的;不然称为不稳定的。bash
--------------------------- 我是分割线--------------------------------——————————————————————————————————ui
以上是教材定义,非小菜所讲,其实一个概念都可用几个特性来描述,对于桶排序,简单来讲有以下特性:this
什么鬼?啥叫桶?咋就时间空间复杂度O(N)了?看客莫急,这样划分咱就能够一一破之啦(在下面的题目中会更加体现);spa
重点来了,题解才是最好的理解code
请听题cdn
// 给定一个数组,求若是排序以后,相邻两个数的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序
class MaxGap {
constructor(){
}
getMax(arr){
if(arr == null || arr.length<2) return 0;
// 数组长度 数组中最大最小值
let len = arr.length,min= arr[0],max= arr[0];
// 桶中是否有数 每一个桶中的最大值 最小值
let hasNum=[],maxs=[],mins=[];
// 遍历数组取最大最小值
for(let i = 0; i<len;i++){
min = Math.min(min,arr[i]);
max = Math.max(max,arr[i]);
// console.log(min,max)
}
if(min == max) return 0;
let bid = 0;
// 循环遍历 将数放在对应范围的桶中 只保留桶中数的max和min 而且将桶的状态改成true
for(let i = 0;i<len;i++){
bid = this.bucket(arr[i],len,min,max);
mins[bid] = hasNum[bid] ? Math.min(mins[bid],arr[i]) : arr[i];
maxs[bid] = hasNum[bid] ? Math.max(maxs[bid],arr[i]) : arr[i];
hasNum[bid] = true;
// console.log(hasNum)
}
// 最大差值
let res = 0;
let lastMax = maxs[0];
let i = 1;
// console.log(hasNum)
for(;i<=len;i++){
// 遍历非空桶min与下一个非空桶的max的差值,最大差值即为res
// 注意,空桶只是杀死了同一个桶中的值的差值不可能为最大,而并不能保证最大差值必定在空桶附近出现
if(hasNum[i]){
res = Math.max(res, mins[i] - lastMax);
lastMax = maxs[i]
}
}
console.log(mins,maxs)
return res;
}
/**
* 求出num对应桶的索引
* @param {目标数} num
* @param {数组长度} len
* @param {数组最小值} min
* @param {数组最大值} max
*/
bucket(num,len,min,max){
// console.log(num,len,min,max)
// console.log((num - min) * len / (max - min))
return parseInt((num - min) * len / (max - min));
}
}
console.log(new MaxGap().getMax([1,3,100,9,8]));
复制代码