题目来源
https://leetcode.com/problems/maximum-gap/description/
题意分析
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
Return 0 if the array contains less than 2 elements.
Example 1:
Input: [3,6,9,1]
Output: 3
Explanation: The sorted form of the array is [1,3,6,9], either
(3,6) or (6,9) has the maximum difference 3.
Example 2:
Input: [10]
Output: 0
Explanation: The array contains less than 2 elements, therefore return 0.
Note:
You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
Try to solve it in linear time/space.
给出一个乱序数组, 求出排序后连续的两个元素间最大差值, 这个差值即是所谓的MaxGap.
元素少于2返回0
尝试在线性空间\时间内解决.
解题思路
这题坦白来讲其实相当的有难度. 博主想了挺久也没有想出可行的线性解.
后来看了讨论区, 原来这道题用桶排序变形一下就好了.
首先, 对一个数组来说, 肯定会有这个公式成立: , 即MaxGap会大于等于排好序的数组的平均间隔, 我们不妨称这个平均间隔为average_gap.
那么我们依据这个average_gap将乱序数组划分为n-2个桶, MaxGap便只可能在相邻的两个桶, 前一个桶的最大值与后一个桶的最小值的差值中产生.
代码实现
import sys
import math
class Solution:
def maximumGap(self, nums):
"""
: type nums : List[int]
: rtype : int
"""
if len(nums) < 2:
return 0
if len(nums)==2:
return int(math.fabs(nums[0]-nums[1]))
Min = sys.maxsize
Max = -sys.maxsize
for num in nums:
if num < Min:
Min = num
if num > Max:
Max = num
# Spilt the array into buckets
average_gap = int(math.ceil((Max - Min) / (len(nums) - 2)))
buckets = [[] for i in range(len(nums) - 2)]
for num in nums:
if num == Min or num == Max:
continue
else:
idx = int(math.floor((num - Min) / average_gap))
buckets[idx].append(num)
# Get the bucket min and bucket max
pre = Min
ret = -sys.maxsize
for bucket in buckets:
if not bucket:
pass
else:
ret = max(min(bucket) - pre, ret)
pre = max(bucket)
return max(ret,Max-pre)
代码表现
代码表现差强人意. 后来反思了一下还可以做点小优化, 那就是用空间换时间, 事先保存好每个桶的最大值和最小值, 这样每次把新的元素加入桶中时都维护好最大值和最小值.
汇总求MaxGap时便可以直接拿来用而不用再用一遍max和min方法.