标签:
博客已经搬家!请前往http://gqqnbig.me/?p=91 阅读本文。
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
Try to solve it in linear time/space.
Return 0 if the array contains less than 2 elements.
You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
函数的值域是0(所有元素相同)到
比较排序的时间复杂度是
第二,假设数组中最小值是min,最大值是max,数组长度为n,则有
例如
| 1| 1| 1| 1| 2| x--x--x--x--x--x | | | | | | 0 10
这里把数组划分为虚拟的n-1组,设每组含头不含尾(除了最后一组),那么每组都划分到1个元素,即最小值(0)和最大值(10)之间的元素是均匀分布的。间隔都是
如果有元素没有平均分布,
| 1| 0| 2| 1| 2| x-----x-x-x--x-x | | | | | | 0 10
那么MaxGap就会大于2。同时可见第二组没有划分到元素,而第三组有2个元素。
把上面的均匀划分的组作为桶,应用桶排序的思想,把数组元素归到桶中。在一个桶内,元素差小于等于block.max-block.min。在两桶之间,元素差等于block2.min-block1.max。
public
int
maximumGap2( int [] num) { if
(num == null
|| num.length < 2 ) return
0 ; int
min = gqqnbig.util.Arrays.min(num); int
max = gqqnbig.util.Arrays.max(num); // the minimum possible gap, ceiling of the integer division int
gap = ( int ) Math.ceil(( double ) (max - min) / (num.length
- 1 )); List<Integer>[] blocks = bucketSort(num, num.length -
1 ); // scan the buckets for the max gap int
maxGap = Integer.MIN_VALUE; int
previousMax = min; for
( int
i = 0 ; i < blocks.length; i++) { if
(blocks[i].isEmpty()) continue ; int
bucketsMIN = Collections.min(blocks[i]); int
bucketsMAX = Collections.max(blocks[i]); maxGap = gqqnbig.Math.max(maxGap, bucketsMAX - bucketsMIN, bucketsMIN - previousMax); // update previous bucket value previousMax = bucketsMAX; } maxGap = Math.max(maxGap, max - previousMax); return
maxGap; } /** * 用桶排序算法对arr数组排序,桶的数量由bucketCount指定。 * <p> * 如果bucketCount等于max-min,则返回值退化为int[]; 否则每个桶可能含有多于一个元素。 * </p> * 时间复杂度O(arr.length),空间复杂度O(arr.length)。 *
* @param arr * @return */ public
static
List<Integer>[] bucketSort( int [] arr,
int
bucketCount) { List<Integer>[] buckets =
new
List[bucketCount]; for
( int
i = 0 ; i < buckets.length; i++) buckets[i] =
new
LinkedList<Integer>(); int
min = gqqnbig.util.Arrays.min(arr); int
max = gqqnbig.util.Arrays.max(arr); int
gap = ( int ) Math.ceil((max - min) / ( double ) bucketCount); // 桶的范围是 // [min, min+gap), [min+gap, min+2gap), ... [min+(bucketCount-1)*gap, min+bucketCount*gap] // min+bucketCount*gap>=max for
( int
i = 0 ; i < arr.length; i++) { int
bucketIndex = (arr[i] - min) / gap; if
(bucketIndex == bucketCount) // 桶的范围算头不算尾,但最后一个桶要算尾。 bucketIndex--; buckets[bucketIndex].add(arr[i]); } return
buckets; } |
标签:
原文地址:http://blog.csdn.net/gqqnb/article/details/42142639