164. 最大间距
难度困难293
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
示例 1:
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。
说明:
- 你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
-
请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。
思路解析:
年轻人不讲武德版:
sort O(nlogn) 算一下就好, 啪,很快哦,sort一下直接AC。
因为题目是int 所以 (logN)max=32。 也就是O(32n)其实也不大。
年轻人讲武德版:
O(N) 桶排序。
思路解析:
对于 样例:1 3 9 6 maxVal=9 minVal=1;
首先就是计算间距,显然,当所有数有序且平均时,数组最大间距的最小值最小。 即桶间间距一定大于桶内间距。(不妨找个例子试试)
dis=(maxVal-minVal)/(n-1) 向上取整。即dis=(9-1)/ 3 向上取整 =3。
//提一点 dis=0 return 0 想一想为什么?
其次,根据间距计算桶的数量:
bucketNum=(maxVal-minVal)/dis+1;//不+1的话,可能有些元素会被舍弃,
即bucketNum=8/3+1=3; //这里如果选择2的话,9就会被舍弃。
再者对桶进行更新,保存最大值和最小值。
[1,2,3] [4,5,6][7,8,9] 桶的数据范围
更新之后:
[1,3][6,6][9,9] //最小值最大值
最后,找出桶间间距最大的值即可。
空桶的话不更新。
年轻人不讲武德版AC代码:
class Solution {
public int maximumGap(int[] nums) {
if(nums.length<2)
return 0;
Arrays.sort(nums);
int ans=-1;
for(int i=1;i<nums.length;i++)
ans=Math.max(ans,nums[i]-nums[i-1]);
return ans;
}
}
年轻人讲武德版AC代码:
class Solution {
public int maximumGap(int[] nums) {
int n = nums.length;
if (n < 2)
return 0;
int minVal=Integer.MAX_VALUE;
int maxVal=Integer.MIN_VALUE;
for(int i=0;i<n;i++)
{
minVal=Math.min(minVal,nums[i]);
maxVal=Math.max(maxVal,nums[i]);
}
int temp=(maxVal-minVal)/(n-1);
int dis=(maxVal-minVal)>temp*(n-1)? temp+1 : temp;//n个数有n-1个间隔。 dis为最小的最大间距
if(dis==0)//所有的值相同。
return 0;
int bucketNum=(maxVal-minVal)/dis+1;//不+1的话,可能有些元素会被舍弃,
int [][] bucket =new int [bucketNum][2];
for(int i=0;i<bucketNum;i++)//初始化
Arrays.fill(bucket[i],-1);
for(int i=0;i<n;i++)
{
int bucketId=(nums[i]-minVal)/dis;
if(bucket[bucketId][0]==-1)
{
bucket[bucketId][0]=nums[i];
bucket[bucketId][1]=nums[i];
}
else
{
bucket[bucketId][0]=Math.min(bucket[bucketId][0],nums[i]);
bucket[bucketId][1]=Math.max(bucket[bucketId][1],nums[i]);
}
}
//进一步讲,我们需要考虑有空桶的情况。
int ans=-1;
int i=0;
while(bucket[i][0]==-1)//找到第一个非空桶
i++;
int pre=i;
for(i=pre+1;i<bucketNum;i++)
{
if(bucket[i][0]==-1)
continue;
ans=Math.max(ans,bucket[i][0]-bucket[pre][1]);//桶间间距,后一个桶的最小值减去前一个桶的最大值。
pre=i;
}
return ans;
}
}