164题最大间距之桶排序做法

 

给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。

如果数组元素个数小于 2,则返回 0。

示例:

输入: [3,6,9,1]

输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。

说明:

  你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。

  请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。

class Bucket {
    int min = Integer.MAX_VALUE;
    int max = Integer.MIN_VALUE;
}

public class 题164桶排序 {
    public int maximumGap(int[] nums) {
        if (nums == null || nums.length < 2) {
            return 0;
        }

        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;

        for (int i : nums) {
            min = Math.min(min, i);
            max = Math.max(max, i);
        }
     if(max == min) {
          return 0;
       }
        // 桶长度 = 区间总长度 / 区间总个数
        int bucketSize = Math.max(1, (max - min) / (nums.length - 1));
       
        // 桶个数 = 区间长度 / 桶长度。 由于开闭区间的问题,多加一个桶
     Bucket[] buckets = new Bucket[(max - min) / bucketSize + 1];
        for (int i = 0; i < nums.length; ++i) {
        //定位到桶的时候,一般是 (当前元素 - 最小值) / 桶长度, 这里利用了整数除不尽向下取整的性质
        int loc = (nums[i] - min) / bucketSize; 
            if (buckets[loc] == null) {
                buckets[loc] = new Bucket();
            }
       //桶只记录放入桶中元素的最大值,最小值。每放一个则更新最大值最小值
            buckets[loc].min = Math.min(buckets[loc].min, nums[i]);
            buckets[loc].max = Math.max(buckets[loc].max, nums[i]);
        }

        int previousMax = Integer.MAX_VALUE;    //记录上一个桶的最大值
        int maxGap = Integer.MIN_VALUE;

        for (int i = 0; i < buckets.length; ++i) {
            if (buckets[i] != null && previousMax != Integer.MAX_VALUE) {
                maxGap = Math.max(maxGap, buckets[i].min - previousMax);  //桶间间距比较
            }

            if (buckets[i] != null) {
                previousMax = buckets[i].max;
                maxGap = Math.max(maxGap, buckets[i].max - buckets[i].min); //桶内间距比较
            }
        }

        return maxGap;
    }
}


猜你喜欢

转载自www.cnblogs.com/silvia-man/p/12044465.html