/**
* 有一个整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数的最大差值。
给定一个int数组A和A的大小n,请返回最大的差值。保证数组元素多于1个。
* @author Administrator
*
*/
今天在牛客网刷题时,遇到这么一道题,听完知识点讲解后,稍微有些不理解,后来自己又仔细想了想。现在整理下思路。
这个题中,数组是乱序的,所以很容易想到的解法就是先选择一种排序算法,然后依次迭代找到最小值即可。但是这样的复杂度就依赖与排序算法的复杂度了。若是采用计数排序的话,有些不现实,因为最大值和最小值之间可能会差别比较大,造成空间浪费。
其实说这么多,就是为了说明这个题还有一种解法,就是类似桶排序的算法。
对于 数组中 n 个数,我们用 n+1 个桶来装,而且在构造这n+1个桶的时候,,需要一点技巧。我们把 用 n (注意:此处用 n ,而不是 n+1 )来除 max{A} - min{A} ,这样就把数组中 从最大值到最小值 分成了 n 份,这儿稍微有点绕。可以参考下面的图片进行理解。一开始还以为老师讲错了,后来debug 了下,发现还真是这么回事。利用下面的代码计算每个元素的桶号,这样计算出来的最大元素的桶号正好是最后一桶。 num 表示的桶的数目, 即 n+1 ,value表示当前要入桶的值。
//该方法用来计算对应元素的应该放入的桶号
private int bucket(long value, long num, long max, long min) {
// int tag = (int) ((value-min)/((max-min)/(num-1))); 应该避免这种连续除法的表达式,因为每次处的时候都会舍,到最后结果会相差很大
int tag = (int) ((value-min)*(num-1)/(max-min));
return tag;
}
可以这么理解,我们把这些元素想象成人,元素值的大小就是人的身高,然后根据每个人的身高,决定某个人应该站在哪一级台阶上。站台阶的规则是这样的:最矮的只能站在地上,最高的则站在最高处。因为一共有 n 个数, 但是却有 n+1 个台阶,所以,中间必然有个台阶是没“人” 站的,当然,可能还有另外的台阶也没站人,但是,此时至少有一个是没有站人的,至少有一个,抽屉原理。,而且