Leetcode164 Maximum Gap

Maximum Gap (Leetcode 164)

Solution

前提:数组中的所有数都是整数

考虑将数组(n个数的数组可以有n-1个差值区间)分成n-1段,每一段的长度是x,每一段中的数是一个左开右闭的区间。

如果要满足题目中要求的排序后相邻两个数的最大差值,则需要保证这个最大差值不会出现在被分割出来的每一段中,换言之就是最大差值一定是出现在两段之间(也就是后一段的最小值与前一段的最大值之间的差值)。

假设数组中的最大值是max,最小值是min,分成n-1段后,每一段的长度是x,由于是左开右闭区间,那么每个区间最多有x-1个数(0被忽略了),所以当(x-1)(n-1) 小于max-min的时候,最大差值就一定出现在两段之间,而不会出现在段中。所以(x-1)(n-1)一定小于等于max-min-1,只要计算出x即可。

Coding

package leetcode;

import java.util.Arrays;

/**
 * @author yinrongjie
 * @version 1.0
 * @date 2023/1/28
 * @description Maximum Gap
 */
public class Solution164 {

    static class Range {
        int max;
        int min;
        boolean used;

        public Range() {
            max = Integer.MIN_VALUE;
            min = Integer.MAX_VALUE;
            used = false;
        }
    }

    public int maximumGap(int[] nums) {
        if (nums == null || nums.length < 2) {
            return 0;
        }

        int max = Arrays.stream(nums).max().getAsInt();
        int min = Arrays.stream(nums).min().getAsInt();

        if (max == min) {
            return 0;
        }

        int n = nums.length;
        // 分成n-1段
        Range[] ranges = new Range[n - 1];
        for (int i = 0; i < n - 1; ++i) {
            ranges[i] = new Range();
        }

        // 每个区间的长度x需要小于等于len
        int len = (max - min - 1) / (n - 1) + 1;
        for (int num : nums) {
            if (num == min) {
                // 左开右闭区间,所以不需要考虑最小值
                continue;
            }
            // num分到哪一段中
            int k = (num - min - 1) / len;
            ranges[k].used = true;
            ranges[k].max = Math.max(ranges[k].max, num);
            ranges[k].min = Math.min(ranges[k].min, num);
        }

        int res = 0;
        for (int i = 0, last = min; i < n - 1; ++i) {
            // last表示上一个区间的最大值
            if (ranges[i].used) {
                res = Math.max(res, ranges[i].min - last);
                last = ranges[i].max;
            }
        }
        return res;
    }

}

github地址:https://github.com/Yin-RJ/algorithm

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值