这道题先排序再遍历一遍能够直接AC,但是在讨论区有人提出了使用桶排序的方式,理论上比直接调库排序更加快,但实际上直接调库速度更快。
首先,定义max, min, N分别为数组最大值、最小值、以及数组长度,根据抽屉原理,显然maximum gap ≥ gap = round_up[(max - min) / (N-1)]。反证法如果maximum gap < gap,则会出现 min + (N-1)*maximum gap < max 的矛盾情况。
因此,设置k个桶,分别存放[min, min+gap), [min+gap, min+2*gap), [min+2*gap, min+3*gap)...范围的数字,这样maximum gap的两个数只会出现在不同的桶中,因此只需要对每个桶记录最大值和最小值即可。
import math
class Solution(object):
def maximumGap(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) <= 1:
return 0
min_num = min(nums)
max_num = max(nums)
if max_num - min_num <= 1:
return max_num - min_num
# maximum gap >= gap
gap = int(math.ceil((max_num - min_num) / (len(nums) - 1.0)))
# 桶存放的nums范围=gap
# 通过检查不同桶之间的最大值和最小值的gap可以得到nums数组的maximun gap
# bucket[i]表示第i个桶存放的最小值
bucket = [min_num]
while bucket[-1] + gap - 1 < max_num:
bucket.append(bucket[-1] + gap)
# bucket_info 存放桶中最大值和最小值信息
bucket_info = []
for i in range(len(bucket)):
bucket_info.append([])
for num in nums:
bucket_id = int((num - min_num) // gap)
if not bucket_info[bucket_id]:
bucket_info[bucket_id] = [num, num]
else:
bucket_info[bucket_id][0] = min(bucket_info[bucket_id][0], num)
bucket_info[bucket_id][1] = max(bucket_info[bucket_id][1], num)
result = gap
# 第1个bucket和最后1个bucket一定不为空
last_bucket_max = bucket_info[0][1]
for i in range(1, len(bucket_info)):
if not bucket_info[i]:
continue
buckets_gap = bucket_info[i][0] - last_bucket_max
result = max(result, buckets_gap)
last_bucket_max = bucket_info[i][1]
return result