- 最大间距
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
示例 1:
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。
说明:
你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。
三种方法:
- 排序后依次计算差值,取差值最大值
- 计数排序
- 桶排序
测试用例:
[1,1,1,1,1,5,5,5,5,5]
[1,1,1,1]
[3,6,9,1]
[10]
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
if (n < 2) return 0;
int maxVal = -1, minVal = INT_MAX;
for (int i=0; i<n; i++) {
maxVal = max(maxVal, nums[i]);
minVal = min(minVal, nums[i]);
}
int d = maxVal - minVal;
//if (0 == d) return 0;
int bucketSize = max(1, d / (n - 1));
int bucketNum = d / bucketSize + 1;
int minMax[bucketNum][2];
memset(minMax, -1, sizeof(minMax));
for (int i=0; i<n; i++) {
int num = (nums[i]-minVal) / bucketSize;
minMax[num][0] = minMax[num][0] == -1 ? nums[i] : min(minMax[num][0], nums[i]);
minMax[num][1] = minMax[num][1] == -1 ? nums[i] : max(minMax[num][1], nums[i]);
}
int ans = 0;
int leftMax = minMax[0][1];
for (int i=1; i<bucketNum; i++) {
if (-1 == minMax[i][0]) continue;
ans = max(ans, minMax[i][0]-leftMax);
leftMax = minMax[i][1];
}
return ans;
}
};
/*8ms,8.6MB*/
时间复杂度:O(n+b)≈O(n)。
线性遍历一遍数组中的元素,复杂度为 O(n)。找到桶之间的最大间距需要线性遍历一遍所有的桶,复杂度为 O(b)。所以总复杂度是线性的。
空间复杂度:O(2⋅b)≈O(b) 的额外空间。
每个桶只需要存储最大和最小元素,因此额外空间和桶个数线性相关。
参考链接:https://leetcode-cn.com/problems/maximum-gap/solution/zui-da-jian-ju-by-leetcode/