LeetCode 164. Maximum Gap(最大空隙)

33 篇文章 0 订阅
12 篇文章 0 订阅

原题网址:https://leetcode.com/problems/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.

方法一:先排序在查找。

public class Solution {
    public int maximumGap(int[] nums) {
        if (nums == null || nums.length < 2) return 0;
        Arrays.sort(nums);
        int max = 0;
        for(int i=1; i<nums.length; i++) {
            max = Math.max(max, nums[i]-nums[i-1]);
        }
        return max;
    }
}

方法二:桶排序+鸽笼原理。

public class Solution {
    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 num: nums) {
            if (num < min) min = num;
            if (num > max) max = num;
        }
        if (max - min == 0) return 0;
        int width = (max-min)/nums.length + 1;
        int[] heights = new int[nums.length];
        int[][] buckets = new int[nums.length][2];
        for(int num: nums) {
            int bucket = (num-min) / width;
            if (heights[bucket]==0) {
                buckets[bucket][0] = num;
                heights[bucket] = 1;
            } else if (heights[bucket]==1) {
                buckets[bucket][1] = Math.max(num, buckets[bucket][0]);
                buckets[bucket][0] = Math.min(num, buckets[bucket][0]);
                heights[bucket] = 2;
            } else {
                buckets[bucket][0] = Math.min(num, buckets[bucket][0]);
                buckets[bucket][1] = Math.max(num, buckets[bucket][1]);
            }
        }
        int maxGap = 0;
        int previous = buckets[0][heights[0]-1];
        for(int i=1; i<buckets.length; i++) {
            if (heights[i] == 0) continue;
            if (buckets[i][0] - previous > maxGap) maxGap = buckets[i][0] - previous;
            previous = buckets[i][heights[i]-1];
        }
        return maxGap;
    }
}

可以换一种计算桶宽的方法:

public class Solution {
    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 num: nums) {
            if (num < min) min = num;
            if (num > max) max = num;
        }
        if (max - min == 0) return 0;
        int width = Math.max(1, (max-min)/nums.length);
        int[] heights = new int[(max-min)/width+1];
        int[][] buckets = new int[(max-min)/width+1][2];
        for(int num: nums) {
            int bucket = (num-min) / width;
            if (heights[bucket]==0) {
                buckets[bucket][0] = num;
                heights[bucket] = 1;
            } else if (heights[bucket]==1) {
                buckets[bucket][1] = Math.max(num, buckets[bucket][0]);
                buckets[bucket][0] = Math.min(num, buckets[bucket][0]);
                heights[bucket] = 2;
            } else {
                buckets[bucket][0] = Math.min(num, buckets[bucket][0]);
                buckets[bucket][1] = Math.max(num, buckets[bucket][1]);
            }
        }
        int maxGap = 0;
        int previous = buckets[0][heights[0]-1];
        for(int i=1; i<buckets.length; i++) {
            if (heights[i] == 0) continue;
            if (buckets[i][0] - previous > maxGap) maxGap = buckets[i][0] - previous;
            previous = buckets[i][heights[i]-1];
        }
        return maxGap;
    }
}


也可以使用哈希映射来作为桶:

public class Solution {
    public int maximumGap(int[] nums) {
        if (nums == null || nums.length <= 1) return 0;
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for(int num: nums) {
            min = Math.min(min, num);
            max = Math.max(max, num);
        }
        if (min == max) return 0;
        int size = Math.max(1, (max-min)/nums.length);
        Map<Integer, Bucket> buckets = new HashMap<>();
        for(int num: nums) {
            int key = (num-min)/size;
            Bucket bucket = buckets.get(key);
            if (bucket == null) {
                bucket = new Bucket(num);
                buckets.put(key, bucket);
            } else {
                bucket.put(num);
            }
        }
        int gap = 0;
        Bucket prev = buckets.get(0);
        for(int i=1; i<=(max-min)/size; i++) {
            Bucket bucket = buckets.get(i);
            if (bucket == null) continue;
            gap = Math.max(gap, bucket.min() - prev.max());
            prev = bucket;
        }
        return gap;
    }
}
class Bucket {
    int[] vals = new int[2];
    int count = 0;
    Bucket(int val) {
        vals[0] = val;
        count = 1;
    }
    int max() {
        return vals[count-1];
    }
    int min() {
        return vals[0];
    }
    void put(int val) {
        if (count == 1 && vals[0] == val) return;
        else if (count == 1 && vals[0] < val) vals[count++] = val;
        else if (count == 1 && vals[0] > val) {
            vals[1] = vals[0];
            vals[0] = val;
            count = 2;
        } else if (val < vals[0]) vals[0] = val;
        else if (val > vals[1]) vals[1] = val;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值