解法一:利用计数排序思想
- 利用计数排序的思想,先求出原数组的最大值max与最小值min
的区间长度d(d=max-min+1),以及偏移量offset=min。 - 创建一个长度为d的新数组Array。
- 遍历原数组,每遍历一个元素,就把新数组Array对应下标的值
+1。例如原数组元素的值为n,则将Array[n-min]的值加1。遍历结束
后,Array的一部分元素值变成了1或更高的数值,一部分元素值仍然是
0。 - 遍历新数组Array,统计出Array中最大连续出现0值的次数+1,
即为相邻元素最大差值。
时间复杂度不稳定在 O(n)
如果原数组只有3个元素:1、2、1 000 000,那就要创建长度是1 000 000的数组
代码如下
/**
* 计数排序
*
* @param a 未排序数组
* @return 最大相邻差
*/
public static int getMaxSortedDistance(int[] a) {
int min = a[0];
int max = a[0];
//1.获取最小值,最大值
for (int item : a) {
if (item >= max) {
max = item;
}
if (item <= min) {
min = item;
}
}
//2.计数排序思想
int distance = max - min + 1;
//偏移量
int offset = min;
//创建一个distance长度的数组,存放 a 数组
int[] array = new int[distance];
for (int value : a) {
//原数组元素的值为n,则将Array[n-min]的值加1
array[value - min]++;
}
// 3.遍历新数组,计算最大相邻差
//统计空值数量
int count = 0;
//最大连续数
int maxCount = 0;
//连续的起始位置
int startIndex = 0;
//结束的开始位置
int endIndex = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == 0) {
if (count == 0) {
//记录连续为0的前一个位置
startIndex = i - 1;
}
//统计空值,判断0最多连续出现的次数
count++;
} else {
count = 0;
}
if (count > maxCount) {
maxCount = count;
//记录连续为0的结束位置的最后一个位置
endIndex = i + 1;
}
}
//4.返回最大相邻差
return endIndex - startIndex;
}
解法二:利用桶排序思想
- 利用桶排序的思想,根据原数组的长度n,创建出n个桶,每一个
桶代表一个区间范围。其中第1个桶从原数组的最小值min开始,区间跨
度是(max-min)/(n-1)。 - 遍历原数组,把原数组每一个元素插入到对应的桶中,记录每一
个桶的最大和最小值。 - 遍历所有的桶,统计出每一个桶的最大值,和这个桶右侧非空桶
的最小值的差,数值最大的差即为原数组排序后的相邻最大差值。
时间复杂度稳定在 O(n)
代码如下
/**
* 桶排序实现相邻两位最大差值
*
* @param a 未排序数组
* @return 最大相邻差
*/
public static int getgetMaxSortedDistanceByBucket(int[] a) {
int min = a[0];
int max = a[0];
//1.获取最小值,最大值
for (int value : a) {
if (value >= max) {
max = value;
}
if (value <= min) {
min = value;
}
}
int offset = max - min;
//如果max=min 说明所有元素都相等
if (offset == 0) {
return 0;
}
//2.初始化捅
int bucketNum = a.length;
Bucket[] buckets = new Bucket[bucketNum];
for (int i = 0; i < bucketNum; i++) {
buckets[i] = new Bucket();
}
//3.遍历原始数组,确定每个桶的最大最小值
for (int value : a) {
//确定数组元素所属的桶下标
int index = (value - min) * (bucketNum - 1) / offset;
if (buckets[index].min == null || buckets[index].min > value) {
buckets[index].min = value;
}
if (buckets[index].max == null || buckets[index].max < value) {
buckets[index].max = value;
}
}
//4.遍历桶,找到最大差值
int leftMax = buckets[0].max;
int maxDistance = 0;
for (int i = 1; i < buckets.length; i++) {
if (buckets[i].min == null) {
continue;
}
if (buckets[i].min - leftMax > maxDistance) {
maxDistance = buckets[i].min - leftMax;
}
leftMax=buckets[i].max;
}
return maxDistance;
}
定义Bucket类
static class Bucket {
private Integer min;
private Integer max;
}