代码随想录训练营第60天 | 503.下一个更大元素II ● 42. 接雨水● 84.柱状图中的最大矩形

news2024/11/28 20:42:23

503.下一个更大元素II 

题目链接:https://leetcode.com/problems/next-greater-element-ii/

解法:

由于是循环数组,可以直接把两个数组拼接在一起,然后使用单调栈求下一个最大值。

写法上,可以巧妙一些,循环的长度为2*len(nums),通过 i%len(nums)来实现两次遍历数组。

边界条件:无

时间复杂度:O(n)

空间复杂度:O(n)

class Solution(object):
    def nextGreaterElements(self, nums):
        dp = [-1] * len(nums)
        stack = []
        for i in range(len(nums)*2):
            while stack and nums[i%len(nums)] > nums[stack[-1]]:
                dp[stack[-1]] = nums[i%len(nums)]
                stack.pop()
            stack.append(i%len(nums))
        return dp 

42. 接雨水

题目链接:https://leetcode.com/problems/trapping-rain-water/

解法:

按照列来计算的话,宽度一定是1了,我们再把每一列的雨水的高度求出来就可以了。

每一列雨水的高度,取决于,该列 左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度。

使用双指针来计算。

为了得到两边的最高高度,使用了双指针来遍历,每到一个柱子都向两边遍历一遍,这其实是有重复计算的。我们把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算。

单调栈的做法,代码随想录的解法写得巨复杂,直接不想看了。其实没那么复杂,但是还是很巧妙,主要出来的柱子的顺序不是从左到右的。

这个和每日温度的题目思路很像,只要找到右边第一个更大的元素,就可以把栈头pop,计算雨水面积,因为是从栈头到栈尾递增,那么左边的元素大于等于栈头,就可以储水了。

雨水高度是 min(凹槽左侧高度, 凹槽右侧高度) - 凹槽底部高度。

雨水宽度是 凹槽右侧的下标 - 凹槽左侧的下标 - 1。

题解看leetcode中文区的比较好懂:

边界条件:无

时间复杂度:O(n)

空间复杂度:O(n)

# 单调栈
class Solution(object):
    def trap(self, height):
        stack = [0]
        result = 0
        for i in range(1, len(height)):
            while stack and height[i] > height[stack[-1]]:
                idx = stack.pop()
                if stack:
                    # 如果 stack[-1] 和 idx 对应的值相同,那就面试为0
                    h = min(height[stack[-1]], height[i]) - height[idx]
                    w = i - stack[-1] - 1
                    result += h * w
            stack.append(i)
        return result
# 双指针
class Solution(object):
    def trap(self, height):
        max_left, max_right = [0] * len(height), [0] * len(height)
        max_left[0] = height[0]
        max_right[-1] = height[-1] 
        # 求i左边的最大值
        for i in range(1, len(height)):
            max_left[i] = max(height[i], max_left[i-1])
        # 求i右边的最大值
        for i in range(len(height)-2, -1, -1):
            max_right[i] = max(height[i], max_right[i+1])
        
        result = 0
        for i in range(len(height)):
            # 取决于左遍最大值和右边最大值之间的较小值
            count = min(max_left[i], max_right[i]) - height[i]
            if count > 0:
                result += count
        return result

84. 柱状图中的最大矩形

题目链接:

解法:

这道题,代码随想录连怎能计算矩形的面积都没写,就直接给了代码,默认大家懂了... 

这题看leetcode的中文区解法比较好。

计算矩形的最大面积,可以枚举以每个柱形为高度的最大矩形的面积。

为此,我们需要:

左边看一下,看最多能向左延伸多长,找到大于等于当前柱形高度的最左边元素的下标;
右边看一下,看最多能向右延伸多长;找到大于等于当前柱形高度的最右边元素的下标。
对于每一个位置,我们都这样操作,得到一个矩形面积,求出它们的最大值。

所以,双指针的写法,可以记录每个元素的左边第一个更小元素的下标和右边第一个更小元素的下标,那么面积等于 (right_min - left_min - 1) * height[i].

相比之下,单调栈的写法简洁多了。这里用的单调减栈,也就是栈头到栈尾是递减的(列表表现为从左到右递增)。

42. 接雨水 (opens new window)是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。不同的是,接雨水第一个柱子和最后一个柱子没法储水,但这里第一个柱子和最后一个都要计算以他们为高度的面积,所以heights的前后要插入0。

边界条件:无

时间复杂度:双指针O(n)

空间复杂度:双指针O(n)

# 双指针 
class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        size = len(heights)
        # 两个DP数列储存的均是下标index
        min_left_index = [0] * size
        min_right_index = [0] * size
        result = 0

        # 记录每个柱子的左侧第一个矮一级的柱子的下标
        min_left_index[0] = -1  # 初始化防止while死循环
        for i in range(1, size):
            # 以当前柱子为主心骨,向左迭代寻找次级柱子
            temp = i - 1
            while temp >= 0 and heights[temp] >= heights[i]:
                # 当左侧的柱子持续较高时,尝试这个高柱子自己的次级柱子(DP
                temp = min_left_index[temp]
            # 当找到左侧矮一级的目标柱子时
            min_left_index[i] = temp
        
        # 记录每个柱子的右侧第一个矮一级的柱子的下标
        min_right_index[size-1] = size  # 初始化防止while死循环
        for i in range(size-2, -1, -1):
            # 以当前柱子为主心骨,向右迭代寻找次级柱子
            temp = i + 1
            while temp < size and heights[temp] >= heights[i]:
                # 当右侧的柱子持续较高时,尝试这个高柱子自己的次级柱子(DP
                temp = min_right_index[temp]
            # 当找到右侧矮一级的目标柱子时
            min_right_index[i] = temp
        
        for i in range(size):
            area = heights[i] * (min_right_index[i] - min_left_index[i] - 1)
            result = max(area, result)
        
        return result

class Solution(object):
    def largestRectangleArea(self, heights):
        heights.insert(0, 0)
        heights.append(0)
        stack = [0]
        result = 0
        for i in range(1, len(heights)):
            # 维持的单调减栈,左边元素肯定更小,右边遇到更小的就计算面积
            while stack and heights[i] < heights[stack[-1]]:
                mid_idx = stack.pop()
                if stack:
                    h = heights[mid_idx]
                    w = i - stack[-1] - 1
                    result = max(result, h * w)
            stack.append(i)
        return result

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

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

相关文章

Windows10文件夹加备注

要给文件夹设置备注&#xff0c;首先要简单了解下desktop.ini这个文件。 .ini文件类型&#xff1a;配置设置 在Windows系统中&#xff0c;desktop.ini文件是一个隐藏的受保护的操作系统文件&#xff0c;它是Windows文件夹自定义的一部分&#xff0c;用于记录文件夹的外观和行为…

【HMS Core】机器学习服务热门问题合集

【关键词】 机器学习服务、文本识别、身份证识别 【问题描述1】 机器学习服务的文本识别能力&#xff0c;是否支持草书等&#xff1f; 【解决方案】 草书是不支持的&#xff0c;目前建议使用较为规范的字体测试。 【问题描述2】 机器学习服务是否支持训练模型&#xff1f;…

人们常常下定决心“不改变”

"因为我的性格很悲观" 有的人会觉得一些事情发生&#xff0c;是自己性格使然&#xff0c;改变不了。 但其实性格是可以改变的。 这听起来似乎不太现实&#xff0c;自己的性格就是这样&#xff0c;怎么会改变&#xff1f; 那换种表达&#xff0c;我们看待世界的方式可…

向量数据库的崛起与多元化场景创新

向量数据库的崛起与多元化场景创新 前言&#xff1a; 在当今数字化时代&#xff0c;数据被认为是黄金&#xff0c;对于企业、科学家和决策者而言都具有巨大的价值。然而&#xff0c;随着数据规模的不断增长&#xff0c;有效地管理、存储和检索数据变得愈发复杂。这就引入了向量…

R语言_RColorBrewer包--全平台可用

R语言_RColorBrewer包–全平台可用

基于nodejs+vue畅听校园点歌系统的设计与实现

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

五、 栈和队列

一、栈和队列的定义 栈是先进后出&#xff0c;队列是先进先出 栈的相关操作&#xff1a; stack<Type> stack_name; .push(element) 压入栈顶 .pop() 弹出栈顶 .top() 返回栈顶元素的引用 .empty() 栈为空返回true&#xff0c;否则返回false队列的相关操作&#xff1a;…

2023辽宁省数学建模B题数据驱动的水下导航适配区分类预测完整原创论文分享(python求解)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了辽宁省数学建模B题完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 B用Python&#xff0b;SPSSPRO求解&…

尚硅谷Docker基础篇和Dockerfile超详细整合笔记

Docker基础篇DockerFile Docker&#xff1a;您要如何确保应用能够在这些环境中运行和通过质量检测&#xff1f;并且在部署过程中不出现令人头疼的版本、配置问题&#xff0c;也无需重新编写代码和进行故障修复&#xff1f;而这个就是使用容器。Docker解决了运行环境和配置问题…

程序包com.sun.deploy.net不存在的解决方法

使用package打包程序时&#xff0c;跳出这样的一个错误&#xff1a; 对应报错信息&#xff1a; 找到该目标文件内容&#xff0c;找到com.sun.deploy.net这个包&#xff1a; 删除这一行即可&#xff01;&#xff01; 运行正确。

基于白鲸优化算法BWO的VMD-KELM光伏发电功率预测(matlab代码+可提供讲解)

目录 1 主要内容 白鲸优化算法BWO 变分模态分解VMD 核极限学习机KELM 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序采用白鲸优化算法变分模态分解核极限学习机三种方法组合对短期光伏功率进行预测&#xff0c;当然&#xff0c;该方法同样适用于风电、负荷等方面…

C语言之动态内存管理实现通讯录(完整版)

我们在之前的博客中写过静态版的通讯录&#xff0c;我们今天来写一个动态版的&#xff0c;不需要规定它到底需要多大空间&#xff0c;只要还有内存&#xff0c;我们都可以存放的下&#xff01;同时&#xff0c;函数实现原理&#xff0c;我在通讯录静态版的博客里做了详细的讲解…

虚拟机VirtualBox添加磁盘

一、创建虚拟硬盘 fdisk -l 我们新添加的磁盘/dev/sdb&#xff0c;还没有分区 sdb磁盘分区 fdisk /dev/sdb n 创建一个新分区 选择p添加主分区 我们把所有10GB空间都格式化为一个分区了 。 w 键入w&#xff0c;保存设置并退出&#x…

【Python基础】Python编程入门自学笔记,基础大全,一篇到底!

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

freertos静态创建任务

在开始前先有个小插曲&#xff0c;我的keil的自动补全代码功能使用不了&#xff0c;经过查找是因为之前装51把有的文件覆盖了&#xff0c;照这篇博客就可以解决。 然后之前那份代码我们是动态创建任务&#xff0c;先来说一下动态创建任务和静态创建任务的区别&#xff1a; Fre…

奇元大模型通过备案 360自研两大模型均获批

11月4日&#xff0c;三六零(601360.SH&#xff0c;下称“360”)大模型“奇元大模型”通过备案落地。今年9月&#xff0c;“360智脑大模型”已获批面向公众开放。360公司也成为国内首家两个大模型均通过备案的科技企业。 从大模型定位和应用角度来看&#xff0c;奇元大模型具备…

【Qt控件之QDockWidget 】使用

概述 QDockWidget类提供了一个窗口部件&#xff0c;可以被停靠在QMainWindow中&#xff0c;或作为桌面上的顶层窗口浮动显示。 QDockWidget提供了停靠窗口的概念&#xff0c;也称为工具暂存区或实用程序窗口。停靠窗口是次要窗口&#xff0c;放置在QMainWindow中心窗口周围的停…

Python之Excel数据相关

Excel Microsoft Excel是Microsoft为使用Windows和Apple Macintosh操作系统的电脑编写的一款电子表格软件。直观的界面、出色的计算功能和图表工具&#xff0c;再加上成功的市场营销&#xff0c;使Excel成为最流行的个人计算机数据处理软件。在1993年&#xff0c;作为Microsof…

LabVIEW实现变风量VAV终端干预PID控制

LabVIEW实现变风量VAV终端干预PID控制 变风量&#xff08;VAV&#xff09;控制方法的研究一直是VAV空调研究的重点。单端PID控制在温差较大时&#xff0c;系统容易出现过冲。针对空调终端单端PID控制的不足&#xff0c;设计一种干预控制与PID控制耦合的控制方法。项目使用LabV…

专访HuggingFace CTO:开源崛起、创业故事和AI民主化丨智源独家

导读 HuggingFace CTO Julien Chaumond认为&#xff0c;在大模型时代&#xff0c;AI民主化至关重要。随着大语言模型和复杂人工智能系统的崛起&#xff0c;持续提升AI技术的可及性有助于确保这些技术的获取和控制不集中在少数强大实体手中。技术民主化促进了机会均等&#xff0…