「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」
164. 最大间距
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
示例1:
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9] , 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。
说明:
- 你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
- 请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。
sort暴力求解
思路 由题意我们得知,需要求出排序后的最大间距,那么我们就根据题意来做
具体实现方式:
- 首先要把数组处理成排序的数组,这里直接用sort来进行排序
- 接来下需要比较相邻两个之间的差距,所以我们让当前元素与上个元素进行比较
- 初始化pre为第一个元素
- 遍历整个数组,每次用当前元素减去上一个元素pre作差,因为是升序排序的数组,所以作差已定位正值,并且与max(初始化为0)进行比较,用Math.max来区较大的差来保存在max中 最后直接返回max即可
var maximumGap = function(nums) {
nums.sort((a,b)=>a-b)
var pre = nums[0]
var max = 0
for(var i=1;i<nums.length;i++){
max = Math.max(nums[i]-pre,max)
pre = nums[i]
}
return max;
};
基数排序
思路 由题可得我们需要对数组先进行排序,这里我们使用基数排序
具体步骤:
- 处理边界条件,数组长度小于2直接返回0
- 对于所有元素的各位进行分组,分别放入cnt中,从0到9,每分配一个就统计总数++
- 接着处理cnt前缀和,以此来得到cnt中的i在原数组的具体下标位置信息
- 从后遍历nums,并且通过digit找到cnt中的位置信息,因为cnt中是从数量1开始计数的,反映到数组下标就需要-1,这样来重新排序原数组
- 重复以上步骤直到maxVal<exp就能得到一个有序的数组了
- 进行最大差ret的比较 最后返回ret即可
var maximumGap = function(nums) {
const n = nums.length;
if (n < 2) {
return 0;
}
let exp = 1;
const buf = new Array(n).fill(0);
const maxVal = Math.max(...nums);
while (maxVal >= exp) {
const cnt = new Array(10).fill(0);
for (let i = 0; i < n; i++) {
let digit = Math.floor(nums[i] / exp) % 10;
cnt[digit]++;
}
for (let i = 1; i < 10; i++) {
cnt[i] += cnt[i - 1];
}
for (let i = n - 1; i >= 0; i--) {
let digit = Math.floor(nums[i] / exp) % 10;
buf[cnt[digit] - 1] = nums[i];
cnt[digit]--;
}
nums.splice(0, n, ...buf);
exp *= 10;
}
let ret = 0;
for (let i = 1; i < n; i++) {
ret = Math.max(ret, nums[i] - nums[i - 1]);
}
return ret;
};