LeetCode164——最大间距

版权声明:我的GitHub:https://github.com/617076674。真诚求星! https://blog.csdn.net/qq_41231926/article/details/86377976

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/maximum-gap/description/

题目描述:

知识点:桶排序

思路:桶排序

如果数组中的元素个数小于2,直接返回0即可。

对于n(n >= 2)个元素,假设其中的最大值是max,最小值是min。

如果max和min相等,显然我们应该返回0。

否则,为其准备n + 1个桶,每个桶中的数字区间尽量平均分配,即第一个桶中存放[min, min + capacity)区间内的数字,最后一个桶中存放[max - capacity, max]区间内的数字。显然,max和min已经保证了第一个桶和最后一个桶不是空桶。

显然,将n个元素放进n + 1个桶里,至少会有一个空桶同一个桶内的差值必然小于capacity,而间隔一个空桶的差值必然会大于capacity。因此,最大差值只可能在空桶的两边产生,即空桶的后一个非空桶的最小值减去空桶的前一个非空桶的最大值。

由此计算方式,我们也可以发现,我们无需保存桶中的所有元素,只需保存桶中的最大值和最小值即可,即数组maxBuckets和minBuckets,其初始化均为-1,表示为空桶。

如何一次遍历maxBuckets和minBuckets数组来求出最大差值呢?

我们需要用一个pre指针保存前一个非空桶的最大值,由于min一定在第一个桶,所以第一个桶一定非空,这为我们的计算带来了方便。一旦遇到非空桶,我们就更新结果result和pre指针的值即可。

时间复杂度和空间复杂度均是O(n),其中n为数组中的元素个数。

JAVA代码:

public class Solution {
    public int maximumGap(int[] nums) {
        if (nums.length < 2) {
            return 0;
        }
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > max) {
                max = nums[i];
            }
            if (nums[i] < min) {
                min = nums[i];
            }
        }
        if(min == max){
            return 0;
        }
        int[] maxBuckets = new int[nums.length + 1];
        Arrays.fill(maxBuckets, -1);
        int[] minBuckets = new int[nums.length + 1];
        Arrays.fill(minBuckets, -1);
        int capacity = (int) Math.ceil((double) (max - min) / (nums.length + 1));
        for (int i = 0; i < nums.length; i++) {
            int index = (nums[i] - min) / capacity;
            if (nums[i] == max) {   //最大值放进最后一个桶里
                index = nums.length;
            }
            if (maxBuckets[index] == -1) {
                maxBuckets[index] = nums[i];
            } else if (nums[i] > maxBuckets[index]) {
                maxBuckets[index] = nums[i];
            }
            if (minBuckets[index] == -1) {
                minBuckets[index] = nums[i];
            } else if (nums[i] < minBuckets[index]) {
                minBuckets[index] = nums[i];
            }
        }
        int result = 0;
        int pre = maxBuckets[0];    //第一个桶有min,一定不是空桶
        for (int i = 1; i < maxBuckets.length; i++) {
            if (maxBuckets[i] != -1) {
                result = Math.max(result, minBuckets[i] - pre);
                pre = maxBuckets[i];
            }
        }
        return result;
    }
}

LeetCode解题报告:

猜你喜欢

转载自blog.csdn.net/qq_41231926/article/details/86377976