虽然直接排完序,再求最大差值更快,这里我们还是学一下桶排序。
桶排序主要维护一个bucket,初始bucket【i】= 0,遍历nums,当i存在时,令bucket【i】= 1,表示存在。遍历完nums,bucket中有0,有1,再遍历bucket,如果是1,就加入ans列表中,最后ans中就是排完序的数组。
这题如果使用桶排序,还需要多考虑一层,因为nums【i】范围嘎嘎大。从数学上考虑,发现nums有n个数字,如果已知nums的最大值max和最小值min,那么可以推出最大间距d>=(max-min)//(n-1)。反证一下:如果每个间距d<(max-min)//(n-1),总共nums数组中排完序后x1,x2,....xn,应该有n-1个间距
max - min = Xn - X1 = Xn - Xn-1 + Xn-1 - Xn-2 + ..... X2 - X1 < max- min
有矛盾。综上:最大间距d>=(max-min)//(n-1)。
那么设置桶的宽度为d = (max-min)//(n-1),维护每个桶的最大值和最小值,那么最大间距的两个点Xi和 Xi-1,必然存在不同的桶t1和t2之间,并且最大间距 = t1最小值 - t2最大值。
class Solution:
def maximumGap(self, nums: List[int]) -> int:
MAX, MIN = max(nums), min(nums)
n = len(nums)
if n < 2: return 0
ans = 0
d = max(1, (MAX-MIN) // (n-1) )
t = (MAX-MIN) // d + 1
bucket = [[0, float('inf')] for _ in range(t)]
for num in nums:
idx = (num-MIN) // d
bucket[idx] = [ max(bucket[idx][0], num), min(bucket[idx][1], num)]
pre = -1
for idx in range(t):
if bucket[idx][0] == 0:continue
if pre != -1:
ans = max(ans, bucket[idx][1]- bucket[pre][0])
pre = idx
return ans