class Solution {
public int maximumGap(int[] nums) {
// 1. 选出数组中的最小值 m 和最大值 M
//这里初始化M为最小值的目的是:任何一个值都可以比其大,方便贪心,下面关于m的设置也是基于这个考虑。
int M = Integer.MIN_VALUE
int m = Integer.MAX_VALUE
// 遍历数组,计算出最小值 m 和最大值 M
//这一块就是纯贪心
for (int x : nums) {
M = Math.max(M, x)
m = Math.min(m, x)
}
// 如果最大值和最小值的差小于等于 1,则不能形成大的间隔,直接返回 M - m
if (M - m <= 1) {
return M - m
}
int n = nums.length
// 计算桶的宽度,`d` 是每个桶的理论宽度
// 注意 `(M - m + n - 2) / (n - 1)` 的计算方式是为了向上取整
int d = (M - m + n - 2) / (n - 1)
// 2. 初始化桶
int BucketNum = (M - m) / d +1
int[][] buckets = new int[BucketNum][2]
for (int[] b : buckets) {
b[0] = Integer.MAX_VALUE
b[1] = Integer.MIN_VALUE
}
// 3. 将每个数字放入对应的桶中
for (int x : nums) {
// 计算该数字应该放入哪个桶
int index = (x - m) / d
int[] b = buckets[index]
b[0] = Math.min(b[0], x)
b[1] = Math.max(b[1], x)
}
// 4. 计算最大间隔
int ans = 0
int preMax = Integer.MIN_VALUE
for (int[] b : buckets) {
if (b[0] != Integer.MAX_VALUE) { // 如果桶不为空(即桶内有数字) **此处容易出问题
// 当前桶的最小值减去上一个非空桶的最大值,得到间隔
ans = Math.max(ans, b[0] - preMax)
preMax = b[1]
}
}
return ans
}
}