[python 刷题] 2866 Beautiful Towers II

news2024/12/22 9:38:03

[python 刷题] 2866 Beautiful Towers II

题目如下:

You are given a 0-indexed array maxHeights of n integers.

You are tasked with building n towers in the coordinate line. The ith tower is built at coordinate i and has a height of heights[i].

A configuration of towers is beautiful if the following conditions hold:

  1. 1 <= heights[i] <= maxHeights[i]
  2. heights is a mountain array.

Array heights is a mountain if there exists an index i such that:

  • For all 0 < j <= i, heights[j - 1] <= heights[j]
  • For all i <= k < n - 1, heights[k + 1] <= heights[k]

Return the maximum possible sum of heights of a beautiful configuration of towers.

这个 mountain 的定义,其实图解一下就很好理解了:

  1. 在这里插入图片描述

    这是一个极端案例,另一个极端案例就是 ⛰️ 的顶端在末尾,整个数组都是呈上升趋势

  2. 在这里插入图片描述

  3. 在这里插入图片描述

提炼一下就是,数组的结构大致如下:

在这里插入图片描述

也就是说:

  • 存在 [ 0 , . . . , j − 1 , j ] [0, ..., j - 1, j] [0,...,j1,j] 的区间,其中 n u m s [ j ] ≥ n u m s [ j − 1 ] ≥ . . . ≥ n u m s [ 0 ] nums[j] \ge nums[j - 1] \ge ... \ge nums[0] nums[j]nums[j1]...nums[0],其中 j > 0 j > 0 j>0

  • 存在 [ j , j + 1 , . . . , k ] [j, j + 1, ..., k] [j,j+1,...,k] 的区间,其中 n u m s [ j ] ≥ n u m s [ j + 1 ] ≥ . . . ≥ n u m s [ k ] nums[j] \ge nums[j + 1] \ge ... \ge nums[k] nums[j]nums[j+1]...nums[k],其中 j < = k = l e n ( n u m s ) − 1 j <= k = len(nums) - 1 j<=k=len(nums)1

从图像上来说,这道题其实有点像 84 Largest Rectangle in Histogram,解题思路也是类似的(都是 monotonic stack)

而另一个方面 ,这道题求的又是高度之和,所以又是一个 prefix sum 的变种问题,也因此解题需要将这一部分考虑在其中

完整解题思路如下:

  1. 新建一个 stack 存储遍历过值的下标,新建一个数组存储 l e f t s u m left_sum leftsum 的值

  2. [ 0 , 1 , . . . , l e n ( n u m s ) − 1 ] [0, 1, ..., len(nums) - 1] [0,1,...,len(nums)1] 遍历一遍数组

    每次遍历的过程中都将当前值作为 ⛰️ 的顶点

    因此需要检查 stack 中的值,如果 nums[stack[-1]] 比当前大,就需要将从结果中移除前一座山峰与现在当前高度差

    同时将当前山峰的高度加上去

    完成循环后就能获得 📈 曲线的结果了

  3. [ l e n ( n u m s ) − 1 , l e n ( n u m s ) − 2 , . . . , 1 , 0 ] [len(nums) - 1, len(nums) - 2, ..., 1, 0] [len(nums)1,len(nums)2,...,1,0] 遍历一遍数组

    这是为了获取 ⛰️ 右侧下降的结果

    二者相加,并取最大值就能够获得最终的结果

以第二个 input [6,5,3,9,2,7] 为例跑一遍

  1. 以数组中的第一个值 6 作为山峰

    这里 stack 的值应该是 stack:[0],保存的是下标而不是值

    在这里插入图片描述

  2. 以数组中的第二个值 5 作为山峰

    这时候的山峰是没有前一座山峰高,因此对前一座山进行一下处理。这里处理方式比较粗暴,就是直接把前面的山给挖了,然后通过获取的下标,做一个反向延长,类似于 84 Largest Rectangle in Histogram 的操作。

    最后结果:

    在这里插入图片描述

    这里 stack 中的值更新为正确的下标

  3. 以数组中的第三个值 3 作为山峰

    同样需要反向延长的操作,结果:

    在这里插入图片描述

  4. 以数组中的第四个值 9 作为山峰

    9 作为山峰是可以更高的,因此这里没有对 stack 进行任何一个操作,结果如下:

    在这里插入图片描述

  5. 以数组中的第五个值 2 作为山峰

    在这里插入图片描述

    这里就需要删减两次,最终获得:

    在这里插入图片描述

    stack 我忘了更新了,不过这个循环也用不到 stack 就不补了

  6. 以数组中的最后的值 7 作为山峰

    因为山峰是可以允许作为最高的存在,因此这里不需要做特殊的操作,直接更新 stack 和 left_sum 即可:

    在这里插入图片描述

    stack 我忘了更新了,不过这个循环也用不到 stack 就不补了

到这里, prefix 的处理就做完了,接着反向做 suffix 的处理,逻辑也是一样的,重新初始化 stack 和高度,重新走一遍循环:

  1. 以数组中的最后的值 7 作为山峰,结果如下:

    在这里插入图片描述

    此时的结果为 m a x ( 0 , 17 + 7 − 7 ) max(0, 17 + 7 - 7) max(0,17+77),之所以要 − 7 -7 7 是因为 m a x H e i g h t s [ i ] maxHeights[i] maxHeights[i] 在 prefix 计算添加了一次,suffix 计算也添加了一次

  2. 以数组中的第四个值 7 作为山峰,结果如下:

    在这里插入图片描述

    此时的结果为 m a x ( 17 , 10 + 4 − 2 ) max(17, 10 + 4 - 2) max(17,10+42)

  3. 以数组中的第三个值 9 作为山峰,结果如下:

    在这里插入图片描述

    此时的结果为 m a x ( 17 , 18 + 13 − 9 ) max(17, 18 + 13 - 9) max(17,18+139)

  4. 以此类推…

最终代码如下:

class Solution:
    def maximumSumOfHeights(self, maxHeights):
        left_sum = [0 for _ in maxHeights]
        stack = [] # store [i, h]
        total = 0
        for i, h in enumerate(maxHeights):
            while stack and stack[-1][1] > h:
                j, j_h = stack.pop()
                multiplier = j - stack[-1][0] if stack else j + 1
                # 这里把所有高出当前峰的 ⛰️ 都从结果中扣掉
                total -= j_h * multiplier

            # 然后在加回去,这时候 stack 中如果存在值,那一定比当前 ⛰️ 要小
            # 如果 stack 为空,则代表当前 ⛰️ 可以一直延续到 i = 0
            multiplier = i - stack[-1][0] if stack else i + 1

            total += h * multiplier
            left_sum[i] = total
            stack.append([i, h])

        stack = []
        total = 0
        result = 0

        # 一个反向求解,从 len(maxHeights) - 1, ..., 0 的方向遍历
        # 其余操作与第一个 for loop 一致,唯一需要注意的就是这里的下标计算为
        # [j, j + 1, ..., len(maxHeights)]
        # 第一个 loop 中为
        # [0, 1, ..., j]
        for i in reversed(range(len(maxHeights))):
            while stack and maxHeights[stack[-1]] > maxHeights[i]:
                j = stack.pop()
                multiplier = stack[-1] - j if stack else len(maxHeights) - j
                total -= maxHeights[j] * multiplier

            multiplier = stack[-1] - i if stack else len(maxHeights) - i
            total += maxHeights[i] * multiplier

            result = max(result, total + left_sum[i] - maxHeights[i])
            stack.append(i)

        return result

讲道理我对 LC 的 rating 不是很理解……Largest Rectangle in Histogram(hard) + prefix sum = medium problem…?

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

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

相关文章

Wi-Fi还可以做什么?柯南解释IOT应用

大会报告&#xff1a;无线人工智能技术正在改变世界 Wi-Fi还可以做什么&#xff1f;随着带宽的提升&#xff0c;无线终端可以识别出更多的多径&#xff0c;每条多径都可以视作一个虚拟传感器&#xff0c;以感知周边环境。基于此&#xff0c;越来越多的无线感知产品应运而生。20…

Leetcode1122. 数组的相对排序

Every day a Leetcode 题目来源&#xff1a;1122. 数组的相对排序 解法1&#xff1a;哈希 用集合 set 存储 arr2 中的元素。 遍历数组 arr1 &#xff0c;设当前元素为 num&#xff1a; 如果 num 在 set 中出现&#xff0c;用哈希表 hash 记录 num 和它出现的次数。否则&a…

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG(目前没有完全的解决方案)

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG&#xff08;目前没有完全的解决方案&#xff09; GNSS配置如下&#xff1a; 【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取&#xff08;北斗、GPS和GNSS&#xff09; 测试视频&#xff08;包括BUG复…

大数据毕业设计选题推荐-热门旅游景点数据分析-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

第二章 Python字符串处理

系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…

『亚马逊云科技产品测评』活动征文|搭建基础运维环境

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 目录 1、什么是容器化部署 2、连接到控制台 3、安装docker 3.1 更新…

学习Opencv(蝴蝶书/C++)代码——1.macOS下安装OpenCV4.8.0和QT5.15(C++)

文章目录 1.前置条件-cmake和c2. opencv2.1 opencv安装2.2 opencv测试2.2.1 基本测试2.2.2 opencv里的自带测试图像 2.3 报错2.3.1 MacOSX10.15.sdk/usr/include/sys/cdefs.h:807:2: error: Unsupported architecture2.2.2 电脑上没有安装java(Unable to locate a Java Runtime…

TSINGSEE青犀智能分析网关人员徘徊AI算法应用场景概述

我们的AI边缘计算网关硬件 —— 智能分析网关目前有5个版本&#xff1a;V1、V2、V3、V4、V5&#xff0c;每个版本都能实现对监控视频的智能识别和分析&#xff0c;支持抓拍、记录、告警等&#xff0c;每个版本在算法模型及性能配置上略有不同。硬件可实现的AI检测包括&#xff…

HCIA数据通信——路由协议

数据通信——网络层&#xff08;OSPF基础特性&#xff09;_咕噜跳的博客-CSDN博客 数据通信——网络层&#xff08;RIP与BGP&#xff09;_咕噜跳的博客-CSDN博客 上述是之前写的理论知识部分&#xff0c;懒得在实验中再次提及了。这次做RIP协议以及OSPF协议。不过RIP协议不常用…

哪里能找到可以学习的前端实战项目?

前言 下面是我整理的一些关于GitHub上的前端相关的项目&#xff0c;希望对你有所帮助&#xff0c;整理不易&#xff0c;可以的话不要吝啬你的点赞喜欢收藏哈~ 废话少说&#xff0c;我们直接进入正题——> 实用工具向 1.Echarts Star&#xff1a;55.6k Echarts提供了大量…

【C++】异常【完整版】

目录 1.C语言传统的处理错误的方式 2. C异常概念 3. 异常的使用 3.1 异常的抛出和捕获 3.2 异常的重新抛出 3.3异常安全 3.4 异常规范 4.自定义异常体系 5.C标准库的异常体系 6.异常的优缺点 1.C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 1. 终止程序…

什么是OTP认证?OTP认证服务器有哪些应用场景?

OTP是一次性密码&#xff0c;即只能使用一次的密码。它基于专门的算法&#xff0c;每隔60秒生成一个不可预测的随机数字组合。这种密码的有效期仅在一次会话或交易过程中&#xff0c;因此不容易受到重放攻击。在计算器系统或其他数字设备上&#xff0c;OTP是一种只能使用一次的…

重定向-缓冲区

1.重定向 文件描述符对应的分配规则是什么? 尝试用这个代码 关闭0,1&#xff0c;2文件描述符&#xff0c;看看有什么现象&#xff1f;关闭哪个&#xff0c;你打开的文件fd应该就是哪个 结论&#xff1a; 从0下标开始&#xff0c;寻找最小的没有没使用的数组位置&#xff0c;它…

【算法 | 哈希表 No.1】leetcode 217. 存在重复元素

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

网站如何保护自身安全

随着网络威胁的不断升级&#xff0c;保护网站免受攻击变得尤为重要。网站被攻击不仅可能导致数据泄露和服务中断&#xff0c;还可能损害声誉和客户信任。本文将从时代因素、人为因素和环境因素的角度&#xff0c;探讨如何解决网站被攻击的问题&#xff0c;提供一些简单而实用的…

关于docker网络实践中遇到的问题

1.禁用docker自动修改iptables规则 查看docker.service文件/usr/lib/systemd/system/docker.service 默认在宿主机部署容器&#xff0c;映射了端口的话&#xff0c;docker能自己修改iptables规则&#xff0c;把这些端口暴露到公网。 如果要求这些端口不能暴露到公网&#xf…

启用NTP服务解决Linux系统时间与北京时间不同步问题

一、背景 1、服务器的Linux版本为Linux version 4.18.0-348.7.1.el8_5.x86_64 (mockbuildkbuilder.bsys.centos.org) (gcc version 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)) #1 SMP Wed Dec 22 13:25:12 UTC 2021 2、NTP即Network Time Protocol&#xff08;网络时间协议&am…

路由器基础(七):NAT原理与配置

一、NAT 配置 华为路由器配置NAT 的方式有很多种&#xff0c;考试中可能考到的基本配置方 式主要有EasyIP和通过NAT地址池的方式。图22-7-1是一个典型的通过EasyIP进行NAT的示意图&#xff0c;其中Router出接口GE0/0/1的IP地址为200.100.1.2/24,接口E0/0/1的IP地址为192.168.0.…

VR博物馆:让博物馆传播转化为品牌影响力

随着VR技术的不断进步&#xff0c;VR全景技术已经成为了文化展示和传播的一项重要工具&#xff0c;相较于传统视频、图文等展现方式&#xff0c;VR全景体验更加直观、便捷&#xff0c;其中蕴涵的信息量也更加丰富&#xff0c;这也为公众了解博物馆和历史文化带来了更为深刻的体…

通达信高级操作:市场雷达的配置使用

我们很多时候会被“条件预警”和“市场雷达” 这两个小窗口搞得晕头转向&#xff0c;那么简单说一下这2个小窗口的区别。 在通达信软件的右下角&#xff0c;我们可以看到一排图标&#xff0c;如下图所示&#xff0c;1这个小雷达图标就是 市场雷达&#xff0c;2这个三角图标是条…