给出四段代码,推荐使用基数排序和桶排序,其他两段代码虽然时间效率和空间效率在本题中似乎排名比较靠前,但是不符合题目要求,慎重。
【题目】
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
【示例 1】
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
【示例 2】
输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。
【说明】
你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。
【代码】
【Python】
执行用时:
44 ms, 在所有 Python3 提交中击败了76.02%的用户
内存消耗:
15.3 MB, 在所有 Python3 提交中击败了6.91%的用户
class Solution:
def maximumGap(self, nums: List[int]) -> int:
nums=sorted(nums)
maxgap=0
for i in range(1,len(nums)):
maxgap=max(maxgap,nums[i]-nums[i-1])
return maxgap
【CPP】
执行用时:
4 ms, 在所有 C++ 提交中击败了99.69%的用户
内存消耗:
8.4 MB, 在所有 C++ 提交中击败了98.95%的用户
class Solution {
public:
int maximumGap(vector<int>& nums) {
sort(nums.begin(),nums.end());
int maxgap=0;
cout<<endl;
for(int i=1;i<nums.size();i++)
maxgap=max(maxgap,nums[i]-nums[i-1]);
return maxgap;
}
};
【桶排序】
对两个相邻的桶,用后一个桶的最小值-前一个桶的最大值,就是两个相邻的桶的最小gap。
桶排序的两个核心问题:
每个桶的长度是多少?换句话说,每个桶放置元素的范围是什么?
一共要准备多少个桶?
分析和解答:
1、我们期望将数组中的各个数等距离分配,也就是每个桶的长度相同,也就是对于所有桶来说,桶内最大值减去桶内最小值都是一样的。可以当成公式来记。
每个桶的长度=max(1,⌊(max(nums)-min(nums)/(len(nums)-1⌋)
2、确定桶的数量,最后的加一保证了数组的最大值也能分到一个桶。
桶的数量 =⌊(max(nums)-min(nums)/桶的长度⌋+1
3、我们的做法是要将数组中的数放到一个个桶里面,不断更新更大的(后一个桶内元素的最小值 - 前一个桶内元素的最大值),最后就得到了答案。
4、如何确定每个数应该对应哪个桶?
location=(nums[i]-min(nums))/每个桶的长度
class Solution:
def maximumGap(self, nums: List[int]) -> int:
if len(nums) < 2: return 0
# 一些初始化
max_ = max(nums)
min_ = min(nums)
max_gap = 0
each_bucket_len = max(1,(max_-min_) // (len(nums)-1))
buckets =[[] for _ in range((max_-min_) // each_bucket_len + 1)]
# 把数字放入桶中
for i in range(len(nums)):
loc = (nums[i] - min_) // each_bucket_len
buckets[loc].append(nums[i])
# 遍历桶更新答案
prev_max = float('inf')
for i in range(len(buckets)):
if buckets[i] and prev_max != float('inf'):
max_gap = max(max_gap, min(buckets[i])-prev_max)
if buckets[i]:
prev_max = max(buckets[i])
return max_gap
【基数排序】
class Solution:
def maximumGap(self, nums: List[int]) -> int:
num_maxlen=0
for n in nums:
num_maxlen=max(num_maxlen,len(str(n)))
for loop in range(1,num_maxlen+1):
buckets=[[] for _ in range(10)]
for n in nums:
buckets[(n//pow(10,loop-1))%10].append(n)
nums=[]
for bucket in buckets:
nums.extend(bucket)
num_maxlen=0
for i in range(1,len(nums)):
num_maxlen=max(num_maxlen,nums[i]-nums[i-1])
return num_maxlen