1. LeetCode 164 最大间距问题解析
这道题目要求我们在线性时间和空间复杂度内,找到一个未排序数组中排序后相邻元素的最大差值。乍看简单,但线性时间复杂度的限制让常规排序方法失效,这正是这道题的巧妙之处。
1.1 问题核心与难点
题目给定一个整数数组nums,要求返回其排序形式中两个连续元素之间的最大差值。如果数组元素少于2个,直接返回0。关键在于必须设计一个时间复杂度为O(n)的算法。
常规思路会先排序再遍历,但即使使用快速排序也需要O(nlogn)时间,不符合要求。这就是为什么我们需要引入桶排序的变种——这是一种能在特定条件下实现线性时间复杂度的巧妙方法。
提示:当题目要求线性时间复杂度时,通常意味着需要使用非比较排序算法,或者利用问题本身的数学特性进行优化。
1.2 桶排序的数学基础
桶排序在这里的应用基于一个关键数学观察:对于n个分布在[lo, hi]区间的数,最大间距至少为(hi - lo)/(n-1)。这个结论来自鸽巢原理——如果将n-1个鸽子均匀放入n-2个鸽巢,必然存在至少一个鸽巢包含多个鸽子。
应用到我们的问题:
- 计算最小值和最大值(O(n))
- 确定桶的大小为ceil((hi-lo)/(n-1))
- 创建n-1个桶(而非传统的n个)
- 每个桶只需记录最大值和最小值
这样设计的精妙之处在于:最大间距必然出现在不同桶之间,而非桶内部。因为桶内部的最大差值不会超过桶大小,而最大间距至少为桶大小。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法实现细节
2.1 预处理阶段
首先需要处理边界情况并获取关键统计量:
java复制if (nums.length < 2) return 0;
int hi = Integer.MIN_VALUE, lo = Integer.MAX_VALUE;
for (int n : nums) {
hi = Math.max(hi, n);
lo = Math.min(lo, n);
}
if (hi == lo) return 0; // 所有元素相同
这一步确保了我们处理了空数组、单元素数组以及所有元素相同的情况,这些都是容易忽略的边界条件。
2.2 桶的初始化
确定桶的大小和数量是关键:
java复制int bucketS
