【每日一题】美丽塔 II

Tag

【单调栈】【数组】【2023-12-21】


题目来源

2866. 美丽塔 II


题目解读

题目意思相对明确,所谓的美丽塔数组就是山状数组,即有一个高度为 maxHeight[i] 的山峰,山峰两侧的高度要小于 maxHeight[i] 并且小于各自的允许高度。需要找出满足以上条件的美丽塔数组,返回数组和。


方法一:暴力枚举

暴力枚举即以每一个整数元素作为山峰,对左右两侧的山峰高度依次处理,取出所有山峰中美丽塔数组的最大值。处理规则如下:

  • 当前的最高山峰下标为 i,此处山峰高度为 maxHeight[i];当前山峰美丽塔的最大值为 res = maxHeight[i]
  • 从下标 i-1 处开始枚举山峰左侧的高度 maxHeight[i-1],如果 maxHeight[i-1] <= maxHeight[i],则下标 i-1 处的山峰高度最大为 maxHeight[i-1],否则下标 i-1 处的山峰高度最大为 maxHeight[i],其实 i-1 处的山峰高度最大为 min(maxHeight[i-1], maxHeight[i])。加到 res 中,枚举完山峰 i 左侧的山,即可得到以下标 i 为山峰的左侧山的高度最大值。
  • 同理,可以得到以下标 i 为山峰的右侧山的高度最大值。
  • 最后,选出枚举所有山峰得到的最大值作为最后的答案。

复杂度分析

时间复杂度: O ( n 2 ) O(n^2) O(n2) n n n 为数组 maxHeight 的长度,对于规模为 1 0 3 10^3 103 甚至 1 0 4 10^4 104 的数据量,该方法可以顺利通过,对于更大规模的数据比如 1 0 5 10^5 105,暴力枚举的方法一定超时,时间复杂度 O ( n ) O(n) O(n) 的解法请看 方法二

空间复杂度: O ( 1 ) O(1) O(1)

方法二:前后缀分解+单调栈

前、后缀的方法在做题时候想到了,但是一直没想通如何计算前、后缀,经过 前后缀分解+单调栈(Python/Java/C++/Go) 思路点拨之后,豁然开朗。

maxHeight 简化为 nums

我们可以借助前后缀的思想,提前计算山峰左侧的递增段的最大和以及山峰右侧递减段最大和。

我们使用数组 pre[i] 表示山峰 nums[i] 左侧的递增段的最大和,使用数组 suf[i] 表示山峰右侧递减段最大和。那么最终的答案为 pre[i] + suf[i+1] 的最大值。

接下来看一下如何计算数组 presuf

使用单调栈,元素值从栈底到栈顶严格递增。

我们先计算 pre,从左到右遍历数组 nums,设当前的元素和为 sum

  • 如果 nums[i] 大于栈顶元素,直接将 nums[i] 加到 sum 中,同时把 i 入栈(栈中只需要保存下标);
  • 否则,只要 nums[i] 小于等于栈顶的元素值,就不断循环,撤销掉原先加入到 sum 中的值。循环结束后,从 nums[i]nums[j-1](假设现在的栈顶下标是 j) 的值都必须是 nums[i],把 nums[i] * (j - i) 加到 sum 中。

现在以数组 nums = [5, 3, 4, 1, 1] 为例,用图示来模拟上述计算 pre[i] 的过程。

(1)初始化单调栈 st,并放入哨兵 -1

(2)遍历数组 nums 开始计算,当前 i = 0:栈 s 的长度为 1 不满足大于 1 的要求,跳过 while 循环;计算当前和 sum = 0 + nums[i] * (i - st.top()) = 5 * (0 - (-1)) = 5;更新 pre[0] = 5,将 0 加入单调栈 st 中。

(3)i = 1:执行 while 循环,st 弹出 0,撤销 sum 中的 5sum = 5 - 5 = 0;当前和 sum = 0 + 3 * (1 - (-1)) = 6;更新 pre[1] = 6,将 1 加入单调栈 st 中。

(4)i = 2:不需要执行 while 循环;当前和 sum = 4 + 3 * (2 - 1) = 10;更新 pre[2] = 10,将 2 加入单调栈 st 中。

(5)i = 3:执行 while 循环,st 弹出 2,先撤销 sum 中的 4sum = 10 - 4 = 6,接着弹出 1 并撤销 sum 中的 23sum = 6 - 2 * 3 = 0;当前和 sum = 0 + 1 * (3 - (-1)) = 4;更新 pre[3] = 4,将 3 加入单调栈 st 中。

(6)i = 4:执行 while 循环,st 弹出 3,撤销 sum 中的 41sum = 4 - 1 * (3 - (-1)) = 0;当前和 sum = 0 + 1 * (4 - (-1)) = 5;更新 pre[4] = 5,将 1 加入单调栈 st 中。

(7)数组 pre 计算完成,pre[i] = [5, 6, 10, 4, 5]

数组 suf 的计算同理,这时候需要从右往左遍历。

实现代码

class Solution {
public:long long maximumSumOfHeights(vector<int>& nums) {int n = nums.size();vector<long long> pre(n), suf(n+1);stack<int> st;st.push(-1);    // 哨兵long long sum = 0;for (int i = 0; i < n; ++i) {int x = nums[i];while (st.size() > 1 && x <= nums[st.top()]) {int j = st.top();st.pop();sum -= (long long) nums[j] * (j - st.top());}sum += (long long) x * (i - st.top());pre[i] = sum;st.push(i);}st = stack<int>(); sum = 0;st.push(n); // 哨兵for (int i = n-1; i >= 0; --i) {int x = nums[i];while (st.size() > 1 && x <= nums[st.top()]) {int j = st.top();st.pop();sum -= (long long) nums[j] * (st.top() - j);}sum += (long long) x * (st.top() - i);suf[i] = sum;st.push(i);}long long res = 0;for (int i = 0; i < n; ++i) {res = max(res, pre[i] + suf[i+1]);}return res;}
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n) n n n 为数组 nums 的长度。

空间复杂度: O ( n ) O(n) O(n),使用的额外空间为记录山峰左侧的最大和。

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

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

相关文章

Simulink仿真中Sine Wave产生的正弦波形不规则,怎么解决

在使用simulink仿真时&#xff0c;使用Sine Wave模块产生的正弦波形不是正弦的&#xff0c;如下所示&#xff1a; 这个是由于simulink仿真中自动计算步长很长的原因导致的&#xff0c;此时需要将自动的步长更改&#xff0c;操作步骤如下所示&#xff1a; 1.点击设置按钮&#…

Unresolved plugin: ‘org.apache.maven.plugins‘解决报错

新建springboot项目报Unresolved plugin: ‘org.apache.maven.plugins:maven-surefire-plugin:3.1.2’ 缺什么插件 引入什么插件的依赖就行 <dependency><groupId>org.apache.maven.plugins</groupId><artifactId>maven-install-plugin</artifact…

如何使用 Helm 在 K8s 上集成 Prometheus 和 Grafana|Part 1

本系列将分成三个部分&#xff0c;您将学习如何使用 Helm 在 Kubernetes 上集成 Prometheus 和 Grafana&#xff0c;以及如何在 Grafana 上创建一个简单的控制面板。Prometheus 和 Grafana 是 Kubernetes 最受欢迎的两种开源监控工具。学习如何使用 Helm 集成这两个工具&#x…

STM32的以太网外设+PHY(LAN8720)使用详解(6):以太网数据接收及发送

0 工具准备 1.野火 stm32f407霸天虎开发板 2.LAN8720数据手册 3.STM32F4xx中文参考手册1 以太网数据接收及发送 1.1 以太网数据接收&#xff08;轮询&#xff09; 1.1.1 检查是否接收到一帧完整报文 使用轮询的方式接收以太网数据是一种简单但是效率低下的方法&#xff0c;…

2023 下半年系统架构设计师学习进度

文章目录 复习计划&#xff1a;每周350分钟第一周&#xff08;339分钟&#xff09;第二周&#xff08;265分钟&#xff09;第三周&#xff08;171分钟&#xff09;第四周&#xff08;214分钟&#xff09;第五周&#xff08;274分钟&#xff09;第六周&#xff08;191分钟&#…

im6ull学习归纳总结(一)APP——04_文件IO

4.1文件从何而来 如图所示文件可以是 1真实文件保存在设备上 2内核提供的虚拟文件 3设备节点 4.2文件的访问方式 4.2.1通用IO模型&#xff1a;open/read/write/lseek/close 实验1 copy文件 代码 #include <sys/types.h> #include <sys/stat.h> #include <fc…

大模型杀入HR赛道,AI能扮演好企业的“人才捕手”吗?

导读&#xff1a;生成式AI如何让HR回归本质。 当很多人焦虑未来会“被AI夺走工作”时&#xff0c;HR行业本身也在AI浪潮推动下发生巨变。 AI技术现已应用于人力资源管理的各个环节中。根据领英发布的《2024全球人才趋势报告》&#xff0c;61%的HR已经在使用AI相关技术辅助日常工…

Python密码魔法:制作个性化、安全性满分的密码生成器秘籍!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 密码是保护个人信息安全的关键&#xff0c;而一个强密码生成器能够帮助用户创建高度安全的密码。本文将介绍如何使用 Python 制作一个简单而功能强大的密码生成器&#xff0c;涵盖了各种生成密码的方法、密码强度…

Linux数据库主从复制(单主单从)

MySQL主从复制的优点包括&#xff1a; 1、横向扩展解决方案 - 在多个从站之间分配负载以提高性能。在此环境中&#xff0c;所有写入和更新都必须在主服务器上进行。但是&#xff0c;读取可以在一个或多个从设备上进行。该模型可以提高写入性能&#xff08;因为主设备专用于更新…

【接口测试】如何定位BUG的产生原因

我们从在日常功能测试过程中对UI的每一次操作说白了就是对一个或者多个接口的一次调用&#xff0c;接口的返回的内容(移动端一般为json)经过前端代码的处理最终展示在页面上。http接口是离我们最近的一层接口&#xff0c;web端和移动端所展示的数据就来自于这层&#xff0c;那么…

用C爬取人人文库并分析实现免积分下载资料

最近有个学妹学习遇到问题&#xff0c;想要的学习资料都在文库中&#xff0c;因为资料太多太杂&#xff0c;想要一篇篇找太难了&#xff0c;主要是太浪费精力了。因此&#xff0c;听说这个事情我能解决&#xff0c;立马找到我&#xff0c;给我一杯奶茶就把我收买了&#xff0c;…

【Seata源码学习 】 扫描@GlobalTransaction注解 篇一

1. SeataAutoConfiguration 自动配置类的加载 基于SpringBoot的starter机制&#xff0c;在应用上下文启动时&#xff0c;会加载SeataAutoConfiguration自动配置类 # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfigurationio.seata.spring.boot.aut…

DPDK单步跟踪(3)-如何利用visual studio 2019和visual gdb来单步调试dpdk

准备工作 因为时间的关系&#xff0c;我想到哪说到哪&#xff0c;可能没那么高的完成度。 但其实有心的人&#xff0c;看到这个标题&#xff0c;就关了本文自己能做了。 why和how to build debug version DPDK,见前两篇。这里我们准备开始。 首先&#xff0c;你有一台linux机…

算法题系列7·获得数组中多数元素

目录 题目描述 实现 提交结果 题目描述 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;…

第11章 GUI Page400~402 步骤二 画直线

运行效果&#xff1a; 源代码&#xff1a; /**************************************************************** Name: wxMyPainterApp.h* Purpose: Defines Application Class* Author: yanzhenxi (3065598272qq.com)* Created: 2023-12-21* Copyright: yanzhen…

黑芝麻智能与亿咖通科技签署战略合作协议,深化协同助力智能驾驶量产落地

12月22日&#xff0c;全球智能汽车计算芯片引领者黑芝麻智能与全球出行科技企业亿咖通科技共同签署战略合作协议&#xff0c;通过深化合作&#xff0c;整合双方研发、产品和技术资源&#xff0c;联手打造领先智能驾驶系统解决方案&#xff0c;合力推进商业拓展和市场应用&#…

微前端样式隔离、sessionStorage、localStorage隔离

1、样式隔离 前端样式不隔离&#xff0c;会产生样式冲突的问题&#xff0c;这个点在qiankun也存在 子应用1修改一个样式 button {background: red&#xff01;important&#xff1b; }其它应用也会受到影响 qiankun的css隔离方案&#xff08;shadow dom&#xff09; shadow …

Hive-high Avaliabl

hive—high Avaliable ​ hive的搭建方式有三种&#xff0c;分别是 ​ 1、Local/Embedded Metastore Database (Derby) ​ 2、Remote Metastore Database ​ 3、Remote Metastore Server ​ 一般情况下&#xff0c;我们在学习的时候直接使用hive –service metastore的方式…

FreeRTOS之二值信号量(实践)

信号量相当于一个标志&#xff0c;实现对资源多少的管理。 比如停车场空位的数量。 这里使用的是二值信号量&#xff0c;其队列长度为1&#xff0c;只有空或满两种状态。 1、步骤&#xff1a; 1.1、创建信号量 1.2、释放信号量 1.3、获取信号量 注&#xff1a;若想深入还…

《深入理解计算机系统》学习笔记 - 第七课 - 机器级别的程序三

Lecture 07 Machine Level Programming III Procedures 机器级别的程序三 文章目录 Lecture 07 Machine Level Programming III Procedures 机器级别的程序三概述程序机制 栈结构栈说明栈定义推入数据弹出数据 调用控制代码示例程序控制流程%rip 传递数据ABI 标准示例 管理局部…