OJ练习第170题——最大间距(桶算法)

news2024/11/26 7:34:24

最大间距

力扣链接:164. 最大间距

题目描述

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

您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。

示例

在这里插入图片描述

Java代码(官解)

class Solution {
    
    // 一步步详解桶算法,因为自己看了很多遍,看的简直头皮发麻
    public int maximumGap(int[] nums) {
        // n
        int n = nums.length;

        // 低于两个数不用比较
        if (n < 2) {
            return 0;
        }

        int minVal = Arrays.stream(nums).min().getAsInt();  // 计算最小值
        int maxVal = Arrays.stream(nums).max().getAsInt();  // 计算最大值

        // 桶区间大小因子d
        int d = Math.max(1, (maxVal - minVal) / (n - 1));

        // 在目标数组中需要划分的 桶 的个数, +1是为了消除d取整前的小数部分带来的误差(注意运算顺序)
        int bucketSize = (maxVal - minVal) / d + 1;

        /*
        * 注意:头皮开始发麻的代码要来了,抓狂抓狂
        * 刚开始对bucket这个二维数组的作用是一脸懵逼,
        * 其实就是一个bucketSize个长度为2的一维数组,这个一维数组用来记录每个区间的的最大值和最小值
        * // 0下标存的是最小值,1下标存的是最大值
        */
        int[][] bucket = new int[bucketSize][2];

        // 给二维数组赋初始值为-1
        for (int i = 0; i < bucketSize; ++i) {
            Arrays.fill(bucket[i], -1); // 存储 (桶内最小值,桶内最大值) 对, (-1, -1) 表示该桶是空的
        }

        // 遍历
        for (int i = 0; i < n; i++) {
            // 通过此运算用来判断当前元素属于哪个桶区间
            int idx = (nums[i] - minVal) / d;

            // 若区间为空,则此元素是第一次进来,则最大值和最小值都是它
            if (bucket[idx][0] == -1) {
                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]);
            }
        }

        // 经过上面的一系列操作,我们发现,这个二维数组居然出现了顺序结构
        // 现在进行最后一步

        int ret = 0;    // 目标值
        int prev = -1;  // 上一个下标

        // 开始遍历每个桶列表
        for (int i = 0; i < bucketSize; i++) {
            // 判断当前桶区间是否为空,空则跳出
            if (bucket[i][0] == -1) {
                continue;
            }
            // 判断上一个下标是否为空,即是否第一次循环
            if (prev != -1) {
                /*
                * 计算上一个桶区间的最大值,与当前桶区间的的最小值的差
                * 然后与ret目标值比较,取最大值然后替换ret值
                */
                ret = Math.max(ret, bucket[i][0] - bucket[prev][1]);
            }
            prev = i;   // 上一个下标自增
        }
        return ret;
    }
}

详解分析来源:https://leetcode.cn/problems/maximum-gap/solutions/498428/zui-da-jian-ju-by-leetcode-solution/comments/682423

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1005246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件结构化设计-架构真题(二十七)

&#xff08;2019年&#xff09;进程P有8个页面&#xff0c;页号分别为0~7&#xff0c;状态位等于1和0分别表示在内存和不在内部才能。假设系统给P分配4个存储块&#xff0c;如果进程P要访问页面6不在内存&#xff0c;那么应该淘汰号是多少&#xff1f; 答案&#xff1a;页号2 …

docker 方式安装mysql 主从方式keepalived实现高可用

一、环境介绍 二、MySQL安装 在两台服务器上都安装mysql 1、拉取镜像 docker pull mysql:8.0.272、创建挂载目录 mkdir -p /data/mysql/3、运行容器 主节点 docker run \--restartalways \--name master_mysql -p 3306:3306 \-e MYSQL_ROOT_PASSWORD123456 -d \-v /data/m…

glTF和GLB有什么区别?

推荐&#xff1a;使用 NSDT场景编辑器快速搭建3D应用场景 自1960年代末开始以来&#xff0c;3D扫描突飞猛进&#xff0c;彻底改变了我们创建真实世界物体和环境的数字模型的方式。虽然很容易考虑它在建筑、工程和游戏等领域的使用&#xff0c;但实际应用要广泛得多。2023年&…

Fiddler实现android手机抓包

目录 一、fiddler的简介二、安装fiddler三、fiddler设置1.设置HTTPS2.设置允许远程连接3. 重启fillder&#xff0c;使得配置生效4. 查看端口监听 四、android端设置1、首先查看电脑的 IP 地址&#xff0c;确保手机和电脑在同一个局域网内2、设置代理 五、抓包测试 原文链接 一、…

Verilog零基础入门(边看边练与测试仿真)-时序逻辑-笔记(4-6讲)

文章目录 第四讲第五讲第六讲 第四讲 1、计数器 代码&#xff1a; //计数器 timescale 1ns/10ps module counter(clk,res,y); input clk; input res; output[7:0] y;reg[7:0] y; wire[7:0] sum;//1运算的结果&#xff08;1&#xff0…

平安大视野解读宏观经济:看好中国经济长期潜力,资产配置价值凸显

“资产配置多元化是投资中唯一的免费午餐。” 1990年&#xff0c;哈里马科维茨因为他提出的“资产组合选择理论”获得了诺贝尔经济学奖。 如何看待当前国内外宏观经济&#xff0c;如何通过资产配置提升家庭财富健康度&#xff1f;9月4日&#xff0c;平安银行联合《21世纪经济报…

Revit SDK 介绍:CurtainWallGrid 幕墙网格

前言 这个例子介绍如何创建幕墙&#xff0c;以及如何通过 API 编辑幕墙。 内容 运行效果&#xff1a; 创建幕墙 幕墙在 Revit 体系里面属于墙的一种&#xff0c;因此&#xff0c;它对应的 API 类型仍然为 Wall&#xff0c;只是类型有差异。 // WallGeometry::CreateCurt…

机器学习笔记 - 从数学表示的角度看待监督学习

一、概述 监督学习的目标是根据数据进行预测。比如电子邮件垃圾邮件过滤,需要将电子邮件(数据实例)分类为垃圾邮件或非垃圾邮件。 按照传统计算机科学的方法,需要编写一个精心设计的程序,遵循一些规则来确定电子邮件是否是垃圾邮件。尽管这样的程序可能在一段时间内运行得…

Apache解析漏洞实验

实验目的 了解Apache解析漏洞原理掌握Apache漏洞的利用方法 实验工具 火狐&#xff1a;Mozilla Firefox&#xff0c;中文俗称“火狐”&#xff08;正式缩写为Fx或fx&#xff0c;非正式缩写为FF&#xff09;&#xff0c;是一个自由及开放源代码网页浏览器&#xff0c;使用Gec…

RPC项目解析(1)

分布式通信框架&#xff1a;让远程方法调用和调用进程内方法一样简单 RPC通信原理 rpc&#xff1a;远程过程调用&#xff08;远程能够调用其他模块的方法&#xff09; 在rpc中需要发送时候&#xff0c;对发送的信息进行序列化&#xff0c;在服务端对接收到的信息进行反序列化…

【C++11新特性】function包装器

文章目录 1. function包装器1.1 function包装器介绍1.2 function包装器对类型的统一1.3 function包装器的意义 1. function包装器 1.1 function包装器介绍 function包装器是一种函数包装器&#xff0c;也叫做适配器。它可以对可调用对象进行包装&#xff0c;C中的function本质…

C++【C++学习笔记_Wang】

时间进度C是什么&#xff1f;多态什么是多态&#xff1f;生活中的多态C中的多态 赋值兼容赋值兼容规则实现安全转换 时间进度 Day101 ok Day804 ok Day805 ok C是什么&#xff1f; C大部分包含C语言。 C完全兼容C语言。 C在C语言的基础上添加&#xff1a;封装、继承、多态…

【SpringMVC】JSR 303与interceptor拦截器快速入门

目录 一、JSR303 1、什么是JSR 303&#xff1f; 2、为什么要使用JSR 303&#xff1f; 3、JSR 303常用注解 3.1、常用的JSR 303注解 3.2、Validated与Valid区别 3.2.1、Validated 3.2.2、Valid 3.2.3、区别 4、使用案例 4.1、导入依赖 4.2、配置校验规则 4.3、编写…

vue基础知识九:动态给vue的data添加一个新的属性时会发生什么?怎样解决?

一、直接添加属性的问题 我们从一个例子开始 定义一个p标签&#xff0c;通过v-for指令进行遍历 然后给botton标签绑定点击事件&#xff0c;我们预期点击按钮时&#xff0c;数据新增一个属性&#xff0c;界面也 新增一行 <p v-for"(value,key) in item" :key&q…

QQ 逻辑漏洞可执行文件 漏洞复现

本文由掌控安全学院- wax 投稿 首先拿到QQ的版本&#xff0c;目前可测试版本包括QQ最新版本&#xff0c;TIM最新版本 新创建一个bat文件&#xff08;这个可以随意&#xff0c;上马的也可以&#xff0c;exe也可以&#xff09; &#xff0c;本次测试内容如下首先向你的手机端发一…

一文告诉你什么是 TCP 数据粘包,该如何解决!

粘包问题概述 描述背景 采用TCP协议进行网络数据传送的软件设计中&#xff0c;普遍存在粘包问题。这主要是由于现代操作系统的网络传输机制所产生的。 我们知道&#xff0c;网络通信采用的套接字(socket)技术&#xff0c;其实现实际是由系统内核提供一片连续缓存&#xff08…

如何实现高效客户服务自助?

随着科技的不断发展&#xff0c;越来越多的企业开始意识到提供良好的客户服务对于企业的重要性。而在满足客户需求的同时&#xff0c;高效实现客户服务自助也成为了许多企业关注的焦点。客户服务自助可以帮助企业降低成本、提高效率&#xff0c;同时也能给客户带来更好的体验。…

[每周一更]-(第60期):15种MySQL索引失效场景

背景 工作中都会踩到Mysql数据库不走索引的坑。常见的现象就是&#xff1a;明明在字段上添加了索引&#xff0c;但却并未生效。 另外&#xff0c;无论是面试或是日常&#xff0c;Mysql索引失效的通常情况都应该了解和学习。 为了方便学习和记忆&#xff0c;这篇文件将常见的15种…

人大女王金融硕士项目——当你觉得迷茫的时候,就去学习来充实自己

不要总以为自己的努力会付之东流&#xff0c;不要因为现在的生活或工作还是依旧没有起色&#xff0c;而想太多。继续努力就好&#xff0c;哪怕明天没有惊喜&#xff0c;但最终的你&#xff0c;却在慢慢的变好。对于从业多年的在职人员来说&#xff0c;职业瓶颈期是非常普遍的。…

JDK多版本切换

为什么切换 因为可能不同项目要求JDK的版本不同&#xff0c;比如你上次装的jdk1.8&#xff0c;现在的项目要求JDK9&#xff0c;这时候卸载8再换9有点费劲&#xff0c;而且操作不当可能遇到非常离奇的bug&#xff0c;影响开发进度。如果我们能灵活切换各种jdk版本&#xff0c;将…