題目:
給定乙個陣列,求如果排序之後,相鄰兩數的最大差值,要求時間複雜度o(n),且要求不能用非基於比較的排序。
例:[3,1,6,2,7]排序後得到[1,2,3,6,7],並且相鄰兩數的最大差值是3(元素3和元素6的差值)。
解決思路:
利用到桶的思想,陣列有n個數,定義n+1個桶,遍歷陣列找到最小值和最大值,放在桶的前後兩端。然後min-max範圍之間的數,分成n+1份,元素屬於哪個範圍,就放到哪個桶內。例子:設陣列長度為9,最小值是0,最大值是99!則需要準備10個桶,0放在0號桶,99放在9號桶。則0-99範圍的數分成10份,即0-9、10-19、......、90-99這10個區間,也就是10個桶。所以元素屬於哪個範圍,就放到哪個桶內。
因為首尾兩個桶必不為空,則中間至少有乙個空桶。則排序後的相鄰兩個數既可能來自同乙個桶,也可能來自不同桶。則依據該空桶,找到該空桶左邊最近的非空桶和右邊最近的非空桶,此時左邊非空桶中的最大值和右邊非空桶中的最小值,在排序後絕對是相鄰的,而此時這兩個極值的差值又絕對比桶的範圍要大,也就是說肯定比乙個桶內的兩個元素差值大。所以說,最大差值只能來自不同的桶內元素。因此只需要統計每個桶內的最小值和最大值即可,不用記錄進入桶內的每乙個元素。但是,需要注意的是,空桶兩側的非空桶差值不一定就是最大的差值。比如:桶10-19內只有值為19的元素,桶20-29為空,桶30-39內只有值為30的元素,桶40-49內只有值為49的元素,此時很明顯最大差值不來自於空桶兩邊的非空桶。故在遍歷桶的時候,遇到空桶的時候,就跳過;如果是非空桶,就尋找下乙個非空桶,記錄其差值,並與最大差值進行比較,遍歷完即可。
**實現:
package com.gxu.dawnlab_algorithm1$2;
/** * 給定乙個陣列,求如果排序之後,相鄰兩數的最大差值,要求時間複雜度o(n),且要求不能用非基於比較的排序。
* @author junbin
* * 2023年4月12日
*/public class maxgap
int len = arr.length;
int min = integer.max_value;
int max = integer.min_value;
for (int i = 0; i < arr.length; i++)
if(min == max)
boolean hasnum = new boolean[len+1];
int maxs = new int[len+1];
int mins = new int[len+1];
int bid = 0; //幾號桶
//分桶並對比
for (int i = 0; i < len; i++)
int res = 0;//最終結果
int lastmax = maxs[0];//距離當前桶左邊最近的非空桶
for(int i = 1;i} return res;
}public static int bucket(int num,int len,int min,int max)
}
演算法 排序 非基於比較的排序
非基於比較的排序與樣本的資料狀況有很大的關係,由於這個限制使其在工程中並不常用。非基於比較的排序有桶排序,基數排序,計數排序。這三者都能做到排序的穩定性,時間複雜度為 o n 空間複雜度為 o n 假設存在一組資料,裡面的資料只有 0 60 使用非基於比較的排序。思路 此時可以使用計數排序,準備 6...
基於C語言的幾道演算法例題
程式 include int main int k,char a 該程式引數,k用來計算引數個數,a用來儲存引數 int b,i,c 1,d 0,nine 0 for i 0 a c i 0 i 使字串引數轉化成實形數 printf you enter is d n d 確認輸入的n是否正確 for...
非基於比較的排序 桶排序
我們最常用的快速排序和堆排序等演算法需要對序列中的資料進行比較,因為被稱為基於比較的排序。而非基於比較的排序有計數排序,桶排序,和在此基礎上的基數排序。要注意的是,非基於比較的排序演算法的使用都是有條件限制的,例如元素的大小限制。假設待排序資料是乙個隨機過程產生,該過程將元素一致地分布在某區間上。桶...