Maximum Gap

Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

Try to solve it in linear time/space.

Return 0 if the array contains less than 2 elements.

You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.


题意:给定一个未排序的数组,返回其排序后的数组中 相邻元素之差 最大的值。

比如给定:[5,9,8,3,15]

排序后为:[3,5,8,9,15],相邻元素之差最大的是15-9=6,返回6。

复杂度要求:时间空间均为O(n)。


Suppose there are N elements in the array, the min value is min and the max value is max. Then the maximum gap will be no smaller than ceiling[(max - min ) / (N - 1)].

Let gap = ceiling[(max - min ) / (N - 1)]. We divide all numbers in the array into n-1 buckets, where k-th bucket contains all numbers in [min + (k-1)gap, min + k*gap). Since there are n-2 numbers that are not equal min or max and there are n-1 buckets, at least one of the buckets are empty. We only need to store the largest number and the smallest number in each bucket.

After we put all the numbers into the buckets. We can scan the buckets sequentially and get the max gap.


public class Solution {
    public int maximumGap(int[] num) {
        if (num == null || num.length < 2)
            return 0;
        // get the max and min value of the array
        int min = num[0];
        int max = num[0];
        for (int i:num) {
            min = Math.min(min, i);
            max = Math.max(max, i);
        }
        // the minimum possibale gap, ceiling of the integer division
        int gap = (int)Math.ceil((double)(max - min)/(num.length - 1));
        int[] bucketsMIN = new int[num.length - 1]; // store the min value in that bucket
        int[] bucketsMAX = new int[num.length - 1]; // store the max value in that bucket
        Arrays.fill(bucketsMIN, Integer.MAX_VALUE);
        Arrays.fill(bucketsMAX, Integer.MIN_VALUE);
        // put numbers into buckets
        for (int i:num) {
            if (i == min || i == max)
                continue;
            int idx = (i - min) / gap; // index of the right position in the buckets
            bucketsMIN[idx] = Math.min(i, bucketsMIN[idx]);
            bucketsMAX[idx] = Math.max(i, bucketsMAX[idx]);
        }
        // scan the buckets for the max gap
        int maxGap = Integer.MIN_VALUE;
        int previous = min;
        for (int i = 0; i < num.length - 1; i++) {
            if (bucketsMIN[i] == Integer.MAX_VALUE && bucketsMAX[i] == Integer.MIN_VALUE)
                // empty bucket
                continue;
            // min value minus the previous value is the current gap
            maxGap = Math.max(maxGap, bucketsMIN[i] - previous);
            // update previous bucket value
            previous = bucketsMAX[i];
        }
        maxGap = Math.max(maxGap, max - previous); // updata the final max value gap
        return maxGap;
    }
}


题目描述: 给定一个无序的数组 nums,返回数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 0。 要求: 你必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例: 输入: [3,6,9,1] 输出: 3 解释: 排序后的数组是 [1,3,6,9],其中相邻元素 (3,6) 和 (6,9) 之间都存在 3 的差值。 解题思路: 要求线性时间和空间,可以想到桶排序。首先遍历一遍数组,找到最大值和最小值,确定桶的大小和数量。将元素按照一定的规则放入桶中,然后在桶内寻找相邻元素之间的最大差值。 由于题目要求相邻元素之间的最大差值,因此可以将桶的大小设为 max(1, (max-min)/(n-1)),其中 n 为数组的长度,这样可以保证桶内相邻元素之间的差值不会超过桶的大小。 放入桶中的规则可以是:假设桶的数量为 n,那么第 i 个元素所在的桶的编号为 (num[i]-min) * n / (max-min),这样就可以保证相邻元素在同一个桶中,而不同的桶之间一定存在空桶。 放入桶中后,从左到右依次遍历桶,用当前桶的最小值减去前一个桶的最大值,得到相邻元素之间的差值,取最大值即可。 Python代码实现: ```python class Solution: def maximumGap(self, nums: List[int]) -> int: n = len(nums) if n < 2: return 0 # 找到最大值和最小值 max_num, min_num = max(nums), min(nums) # 计算桶的大小和数量 bucket_size = max(1, (max_num - min_num) // (n - 1)) bucket_num = (max_num - min_num) // bucket_size + 1 # 初始化桶 bucket = [[float('inf'), float('-inf')] for _ in range(bucket_num)] for num in nums: # 计算元素所在的桶的编号 idx = (num - min_num) // bucket_size # 更新桶的最大值和最小值 bucket[idx][0] = min(bucket[idx][0], num) bucket[idx][1] = max(bucket[idx][1], num) # 遍历桶,计算相邻元素之间的最大差值 res, pre_max = 0, bucket[0][1] for i in range(1, bucket_num): if bucket[i][0] == float('inf'): continue res = max(res, bucket[i][0] -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值