LeetCode:LCP 24. 数字游戏(对顶堆求中位数 Java)

2024-02-02 21:28

本文主要是介绍LeetCode:LCP 24. 数字游戏(对顶堆求中位数 Java),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

LCP 24. 数字游戏

题目描述:

实现代码与解析:

原理思路:


LCP 24. 数字游戏

题目描述:

        小扣在秋日市集入口处发现了一个数字游戏。主办方共有 N 个计数器,计数器编号为 0 ~ N-1。每个计数器上分别显示了一个数字,小扣按计数器编号升序将所显示的数字记于数组 nums。每个计数器上有两个按钮,分别可以实现将显示数字加一或减一。小扣每一次操作可以选择一个计数器,按下加一或减一按钮。

主办方请小扣回答出一个长度为 N 的数组,第 i 个元素(0 <= i < N)表示将 0~i 号计数器 初始 所示数字操作成满足所有条件 nums[a]+1 == nums[a+1],(0 <= a < i) 的最小操作数。回答正确方可进入秋日市集。

由于答案可能很大,请将每个最小操作数对 1,000,000,007 取余。

示例 1:

输入:nums = [3,4,5,1,6,7]

输出:[0,0,0,5,6,7]

解释: i = 0,[3] 无需操作 i = 1,[3,4] 无需操作; i = 2,[3,4,5] 无需操作; i = 3,将 [3,4,5,1] 操作成 [3,4,5,6], 最少 5 次操作; i = 4,将 [3,4,5,1,6] 操作成 [3,4,5,6,7], 最少 6 次操作; i = 5,将 [3,4,5,1,6,7] 操作成 [3,4,5,6,7,8],最少 7 次操作; 返回 [0,0,0,5,6,7]。

示例 2:

输入:nums = [1,2,3,4,5]

输出:[0,0,0,0,0]

解释:对于任意计数器编号 i 都无需操作。

示例 3:

输入:nums = [1,1,1,2,3,4]

输出:[0,1,2,3,3,3]

解释: i = 0,无需操作; i = 1,将 [1,1] 操作成 [1,2] 或 [0,1] 最少 1 次操作; i = 2,将 [1,1,1] 操作成 [1,2,3] 或 [0,1,2],最少 2 次操作; i = 3,将 [1,1,1,2] 操作成 [1,2,3,4] 或 [0,1,2,3],最少 3 次操作; i = 4,将 [1,1,1,2,3] 操作成 [-1,0,1,2,3],最少 3 次操作; i = 5,将 [1,1,1,2,3,4] 操作成 [-1,0,1,2,3,4],最少 3 次操作; 返回 [0,1,2,3,3,3]。

实现代码与解析:

对顶堆求中位数

class Solution {public int[] numsGame(int[] nums) {final int MOD = 1000000007;PriorityQueue<Integer> lq = new PriorityQueue<>((a, b) -> b - a); // 大根堆PriorityQueue<Integer> rq = new PriorityQueue<>(); // 小根堆int n = nums.length;int[] res = new int[n];long lsum = 0;long rsum = 0;for (int i = 0; i < n; i++) {int t = nums[i] - i;if (i % 2 == 0) {lq.offer(t);lsum += t;int j = lq.peek();lq.poll();lsum -= j;rq.offer(j);rsum += j;res[i] = (int) ((rsum - rq.peek() - lsum) % MOD);} else {rq.offer(t);rsum += t;int j = rq.peek();rq.poll();rsum -= j;lq.offer(j);lsum += j;res[i] =  res[i] = (int) ((rsum - lsum) % MOD);}}  return res;}
}

原理思路:

        题目转化:就是所有nums[i] - i 变成相同值的最小和,而这个相同值就是他们的中位数,把这些数放在数轴上就可以很好的观察出来,也可以作为定理记下来。  

        至于为啥是num[i] - i,可以简单证明一下。例如有一个值 a0, a1, a2,假设最后结果为b , b + 1, b + 2,那么和就为|a0 - (b + 0)| + |a1 - (b + 1)| + |a2 - (b + 2)| 等价于sum|(ai - i - b)|,把ai - i 看成一个整体ti,那么就变成了每一个 ti 到某一个值的距离最小和。这个值就是中位数。  

        所以这题的核心就是求中位数,如何求?

就是对顶堆(双优先级队列lq,rq)

- 中位数左的小数用lq大顶堆维护  

- 中位数右的大数用rq小顶堆维护  

- x 为我们正在遍历的数  

- 如果前缀长度是奇数,此时 lq 和 rq 大小相等,我们先把 x 插入 lq,然后弹出 lq 的堆顶,加到 rq 中。这一操作可以保证,无论 x 是大是小,此时 rq 的堆顶就是中位数。  

- 如果前缀长度是偶数,此时 lq 比 rq 少一个元素,我们先把 x 插入 rq,然后弹出 rq 的堆顶,加到 lq 中。

        当然这里是可以优化的,比如奇数时,lq里的最大值都小于x,那么就直接放进rq就好了,就省去了进lq,再出来进rq的步骤,偶数时同理。

        这题只要想到题目转换的含义就很好写了。

这篇关于LeetCode:LCP 24. 数字游戏(对顶堆求中位数 Java)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/672007

相关文章

Java方法重载与重写之同名方法的双面魔法(最新整理)

《Java方法重载与重写之同名方法的双面魔法(最新整理)》文章介绍了Java中的方法重载Overloading和方法重写Overriding的区别联系,方法重载是指在同一个类中,允许存在多个方法名相同... 目录Java方法重载与重写:同名方法的双面魔法方法重载(Overloading):同门师兄弟的不同绝

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位

springboot的controller中如何获取applicatim.yml的配置值

《springboot的controller中如何获取applicatim.yml的配置值》本文介绍了在SpringBoot的Controller中获取application.yml配置值的四种方式,... 目录1. 使用@Value注解(最常用)application.yml 配置Controller 中