一直誤覺得寫文章太耗費費時間,昨日爲尊敬高貴帥氣逼人的導師所一語驚醒(未一舉成名之日,毫不提尊師名諱,嗯,沒錯),分享纔是程序員最快的提高; 今天開始,作不到多寫多練,就不是誠實善良的南方小菜啦程序員
不廢話,直接進入主題算法
桶排序(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]));
複製代碼