LeetCode 使循环数组所有元素相等的最少秒数

地址:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
难度:中等

题目描述:给你一个下标从 0 开始长度为 n 的数组 nums 。
每一秒,你可以对数组执行以下操作:

  • 对于范围在 [0, n - 1] 内的每一个下标 i ,将 nums[i] 替换成 nums[i] ,nums[(i - 1 + n) % n] 或者 nums[(i + 1) % n] 三者之一。

其实就是nums[i]可以替换成它本身或者它的前一位或者后一位的值,这个时候在想边缘怎么办?

把数组看出一个环,num[0]挨着的就是num[8]和num[1]
可以带入计算一下:n = 9 ,i = 0,
(i - 1 + n) % n = (0-1+9)%9 = 8
(i +1 + n) % n = (0+1+9)%9 = 10%9 = 1


注意,所有元素会被同时替换。

也就是一轮替换就是1s
比如可以同时操作num[1]、num[2])替换,等这一轮停止操作了我们得到了一个替换后的数组
入果这个数组没有符合预期,那就需要再进行到下一轮替换

请你返回将数组 nums 中所有元素变成相等元素所需要的 最少 秒数。

思考过程

可以理解为将数组的每一个元素都逐渐替换为数组中的某个值。
我们可以枚举数组中的各种元素,分别计算将所有元素替换为该元素所消耗的时间。
计算过程需要利用该元素在数组中出现的位置

题解

  • 我们首先用哈希表,统计 nums 中相同的数所出现的位置,mp[x]表示 x 所出现的位置。
  • 然后我们研究,使得数组全部变为 x所需要的时间,这个时间取决于 nums中,相邻 x 的最大距离。
  • 我们依次枚举所有相邻(包括头尾)x 的索引值,找到最大的距离。
  • 最大距离除以二并向上取整,就是使得数组全部变为 x 所需要的时间
  • 最后我们对所有 nums中 的数,都找到所需的时间,返回其中的最小值即可。

本质上是扩散的原理

假设现在数组的为 3 2 6 4 9 5 3 1,x是3

分析:
我们能看到两个3之间最大的间隔有5个元素,那需要经过多少轮才能把3之间的元素同步扩散完呢?

第一次扩散(暂时不要关注数字1):

第二次扩散(暂时不要关注数字1):

第三次扩散(暂时不要关注数字1):

可以看到是经过了三次才完成了扩散,正好是5/2在向上取整的结果

为什么是除2?
因为每次两边都能同时扩散推进一个,效率是乘2的,自然最后计算的时候也就是除2啦

那短距离的那边怎么统计呢?
题目说了:所有元素会被同时替换。
也就是说,元素的扩散是同时进行的,长的距离扩散的时候,短的距离也在同步扩散,那个1在第一轮扩散的时候就被替换成3了
时间长的都扩散完了,时间短的其实早就扩散完毕了

代码解析:

function minimumSeconds(nums: number[]): number {const n:number = nums.lengthlet rs:number = nconst mp:Map<number,number[]> = new Map() //存储结果for(let i:number = 0;i<n;i++){if (!mp.has(nums[i])) {mp.set(nums[i], []);}mp.get(nums[i]).push(i);}for(const pos of mp.values()){let mx: number = pos[0] + n - pos[pos.length - 1]-1;//为什么设置这个初始值?// 避免环形的时候最大距离计算错误for (let i: number = 1; i < pos.length; ++i) {mx = Math.max(mx, pos[i] - pos[i - 1]-1);}rs = Math.min(rs, Math.ceil(mx / 2));}return rs
};

解释一下这行代码:number = pos[0] + n - pos[pos.length - 1]-1

我们知道我们需要找到的是最大距离,记住数组是环形数组
那么下面的情况,最大长度就会是pos[0] + n - pos[pos.length - 1]-1

如果我们还是拿2-0-1的话,计算出来的是短的距离,结果是1,会导致最终的答案不对

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多线程事务如何回滚?

背景介绍 1&#xff0c;最近有一个大数据量插入的操作入库的业务场景&#xff0c;需要先做一些其他修改操作&#xff0c;然后在执行插入操作&#xff0c;由于插入数据可能会很多&#xff0c;用到多线程去拆分数据并行处理来提高响应时间&#xff0c;如果有一个线程执行失败&am…

基础知识总结

概念概述 计算机网络是通过传输介质、通信设施和网络通信协议&#xff0c;把分散在不同地点的计算机设备互连起来&#xff0c;实现资源共享和数据传输的系统。而网络编程就是编写程序使联网的两个或多个设备&#xff08;比如计算机&#xff09;之间进行数据传输。Java语言对网…

PHP微信UI在线聊天系统源码 客服私有即时通讯系统

(购买本专栏可免费下载栏目内所有资源不受限制,持续发布中,需要注意的是,本专栏为批量下载专用,并无法保证某款源码或者插件绝对可用,介意不要购买) DuckChat是一套完整的私有即时通讯解决方案,包含服务器端程序和各种客户端程序(包括iOS、Android、PC等)。通过Duck…

鸿蒙 ArkTS 从数组内查找指定的数据

let arr [1, 2, 3, 4, 5]; let target 3; let result arr.filter(item > item target); let a String(result) 将数字转换成文本型 console.log(a); 亲爱的读者&#xff1a; 首先&#xff0c;我要感谢您抽出宝贵的时间阅读这篇文章。我深知&#xff0c;您的每一分每一…

黑马程序员学习:产品卡片

黑马程序员前端web入门&#xff1a;产品卡片 几点学习到的&#xff1a; text-align:center&#xff1b; text-align 属性规定将元素内的文本内容在水平方向上居中对齐&#xff0c;可以设置块级元素内文本的水平对齐方式&#xff0c;但是不能让块级元素内部的块级元素居中。需要…

启动盘重装ubuntu22系统

win+R msinfo32查看 插入制作好的u盘电脑开机 进入BIOS界面的方法有多种,以下是一些常见的方法: 方法一:通过重启计算机进入BIOS 关闭计算机,等待几秒钟。按下计算机电源按钮,开始启动计算机。在计算机启动时,通常会显示厂商的Logo,如Dell、HP等。在显示Logo的时候…

C++引用详解

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间…

3分钟搞定幻兽帕鲁联机,手动搭建专属服务器

《幻兽帕鲁》的热潮正在席卷游戏界。对于那些更喜欢与熟悉的伙伴们共同探险的玩家来说&#xff0c;搭建一个私人服务器无疑是最佳选择。拥有个人服务器不仅意味着更高的隐私性&#xff0c;还允许你根据喜好调整游戏参数&#xff0c;比如改变游戏内的工作速度倍率、经验值获取倍…

MacBook安装虚拟机VMware Fusion

MacBook安装虚拟机VMware Fusion 官方下载地址: https://customerconnect.vmware.com/cn/downloads/info/slug/desktop_end_user_computing/vmware_fusion/11_0 介绍 之前的版本都要收费,现在出了对个人免费的版本, 棋哥给的破解版的版本是8,升级系统后用不了了. 官方去下载…

火山引擎ByteHouse:分析型数据库如何设计并发控制?

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 分析型数据库设计并发控制的主要原因是为了确保数据的完整性和一致性&#xff0c;同时提高数据库的吞吐量和响应速度。并发控制可以防止多个事务同时对同一数据进行…

基于SSM的高校班级同学录网站设计与实现(有报告)。Javaee项目,ssm项目。

演示视频&#xff1a; 基于SSM的高校班级同学录网站设计与实现&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm项目。 项目介绍&#xff1a; Javaee项目&#xff0c;采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&…

ESP32 LED PWM 控制器

ESP32 具有 LED PWM 控制器&#xff0c;具有 16 个独立通道&#xff0c;可配置为生成具有不同属性的 PWM 信号。 使用 Arduino IDE 通过 PWM 对 LED 进行调光时必须遵循以下步骤&#xff1a; 1.首先&#xff0c;您需要选择一个PWM通道。从 0 到 15 有 16 个通道&#xff0c;一…