前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Leetcode No.164 最大间距(桶排序)

Leetcode No.164 最大间距(桶排序)

作者头像
week
发布2022-01-06 10:24:26
5610
发布2022-01-06 10:24:26
举报
文章被收录于专栏:用户画像用户画像

一、题目描述

给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。 如果数组元素个数小于 2,则返回 0。

代码语言:javascript
复制
示例 1:
 输入: [3,6,9,1]
 输出: 3
 解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
 输入: [10]
 输出: 0
 解释: 数组元素个数小于 2,因此返回 0。

说明: 你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。 请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。

二、解题思路

桶排序的两个核心问题:

1、每个桶的长度是多少?换句话说,每个桶放置元素的范围是什么? 2、一共要准备多少个桶?

分析和解答: 1、我们期望将数组中的各个数等距离分配,也就是每个桶的长度相同,也就是对于所有桶来说,桶内最大值减去桶内最小值都是一样的。可以当成公式来记。

2、确定桶的数量,最后的加一保证了数组的最大值也能分到一个桶。

3、我们的做法是要将数组中的数放到一个个桶里面,不断更新更大的(后一个桶内元素的最小值 - 前一个桶内元素的最大值),最后就得到了答案。 4、如何确定每个数应该对应哪个桶?

image.png
image.png

三、代码

代码语言:javascript
复制
public class Solution2 {
    public int maximumGap(int[] nums) {
        int n = nums.length;
        if (n < 2) {
            return 0;
        }
        // 找出最大值和最小值 为了方便后面确定桶的数量
        int minVal = Arrays.stream(nums).min().getAsInt();
        int maxVal = Arrays.stream(nums).max().getAsInt();
        // 确定桶的间距
        int d = Math.max(1, (maxVal - minVal) / (n - 1));
        // 确定桶的个数
        int bucketSize = (maxVal - minVal) / d + 1;
        int[][] bucket = new int[bucketSize][2];
        for (int i = 0; i < bucketSize; ++i) {
            // 存储 (桶内最小值,桶内最大值) 对, (-1, -1) 表示该桶是空的
            Arrays.fill(bucket[i], -1);
        }
        for (int i = 0; i < n; i++) {
            //找到每一个值所对应桶的索引
            int idx = (nums[i] - minVal) / d;
            //该桶是空的
            if (bucket[idx][0] == -1) {
                //最大值和最小值都设置为nums[i]
                bucket[idx][0] = bucket[idx][1] = nums[i];
            } else {
                // 更新每个桶的数据
                bucket[idx][0] = Math.min(bucket[idx][0], nums[i]);
                bucket[idx][1] = Math.max(bucket[idx][1], nums[i]);
            }
        }
        //ret表示桶之间最大的差距
        int ret = 0;
        //preMax 表示前一个桶的最大值
        int prev = -1;
        for (int i = 0; i < bucketSize; i++) {
            //表示某一个桶为空
            if (bucket[i][0] == -1) {
                continue;
            }
            //但凡某一个桶不为空,都会在前面的数据中更新掉bucketMax的值
            if (prev != -1) {
                //用后一个桶的最小值减前一个桶的最大值,可以得到最大间距。
                ret = Math.max(ret, bucket[i][0] - bucket[prev][1]);
            }
            prev = i;
        }
        return ret;
    }
}

四、复杂度分析

时间复杂度:O(N),其中 N 是数组的长度。注意到桶的数量为(max−min)/d≈N−1=O(N)。

空间复杂度:O(N),其中 N 是数组的长度。我们开辟的空间大小取决于桶的数量。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目描述
  • 二、解题思路
  • 三、代码
  • 四、复杂度分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档