力扣● 84.柱状图中最大的矩形

  •  84.柱状图中最大的矩形

需要找到元素i的上一个更小的元素leftmin和下一个更小的元素rightmin,这样leftmin和rightmin之间的元素都比当前元素i更大,那么矩形的宽就是中间的这些元素:可以从leftmin+1延伸到rightmin-1,长即为height[i]。

如下图,5的上一个更小是1,下一个更小是2,所以中间的5、6组成的矩形是以5为高的矩形中最大的,以此类推,以6为高最大是6、以2为高最大是2……

所以整体过程:从0出发,找到以height[栈顶]为高的时候面积最大的矩形,进行比较迭代得到maxarea。

找面积最大矩形就是上面的方法,上一个更小元素就得是次栈顶,下一个更小元素是遍历的元素,那么跟上题接雨水很相似。根据要求,必须使用单调递减栈。

当i比栈顶小,说明i是栈顶的下一个更小元素,那么得到栈顶是mid,上一个更小元素left=次栈顶,下一个更小元素是i,以height[mid]为高的矩形,面积最大的时候就是此时得到:宽为i-left-1。得到面积然后更新maxarea。

当i==栈顶,这里可以更新栈顶,也可以不更新。和接雨水一样,只用到了其元素值而没有用到其下标。

当i>栈顶,就应该直接入栈,不用计算面积,因为以栈顶为高的面积肯定不是最大面积。

如果只是把接雨水的题目改一下条件,将单增栈改为单减栈,程序还是会不对。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        
        int maxarea=0;
        
        int n=heights.size();
        stack<int> st;
        st.push(0);
        //找下一个比自己小的
        for(int i=1;i<n;++i){
            while(!st.empty() && heights[i]<heights[st.top()]){
                int mid = st.top();
                st.pop();
                if(!st.empty() ){
                    int w=i-st.top()-1;
                    int h=heights[mid];//min(heights[i],heights[st.top()]);
                    maxarea=max(w*h,maxarea);
                }
            }
            
            cout<<maxarea<<endl;
            st.push(i);
        }
        return maxarea;
    }
};

比如:

5入栈,4更小,得到right(1),mid(0),要得到left次栈顶,5出栈,栈则为空了,没有left,会跳过计算面积的过程,那么maxarea为0;4入栈,1更小,同样得不到left,maxarea还是0;1入栈,2更大,直接入栈,没有更新maxarea,所以结果是0。

当发生上面那种情况:数组里面存在这种连续递减的序列,而且这个序列的第一个元素进去的时候栈为空,就会持续上面的过程,所以方法是:在heights数组前面加一个0,这样栈里面永远都不会为空,不会跳过计算面积的过程,计算的时候left就为0,意味着栈顶左边没有比自己小的元素,这个矩形就从自己开始,到right-1。

那么如果是连续递增的序列:

1、2、3、4

1入栈,2更大,入栈;3更大,入栈……最后栈里面是这整个连续递增的序列,然后maxarea没有一次更新的过程,因为没有right,每个元素右边都没有比自己小的元素。解决方法是:在heights数组最后面加1个0,这样遍历最后这个元素0的时候,就会把栈里面这些元素都出栈然后计算面积。

所以单纯修改接雨水题目不行,还要解决这个最大矩形可能从自己开始(解决:heights开头加0)和以自己结尾(解决:heights开头加0)的情况。加入这两个之后,栈肯定不会为空,所以所有判断栈空的条件语句都可以省略了:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int maxarea=0;

        heights.insert(heights.begin(),0);
        heights.push_back(0);

        int n=heights.size();
        stack<int> st;
        st.push(0);
        //找下一个比自己小的
        for(int i=1;i<n;++i){
            while( heights[i]<heights[st.top()]){
                int mid = st.top();
                st.pop();
                int w=i-st.top()-1;
                int h=heights[mid];//min(heights[i],heights[st.top()]);
                maxarea=max(w*h,maxarea);
            }
            cout<<maxarea<<endl;
            st.push(i);
        }
        return maxarea;
    }
};

代码随想录训练营的内容,现在才刷完,一刷太慢看太细了,之后按照这个贴子的做法来:

第一遍:5~10分钟:读题+思考。如果不会直接看题解,然后理解题解中的解法,并且比较不同解法的时间和空间的复杂度(一定要对比,我面试的时候就被问了几种解法,一般都是时间最优或者空间最优的解法)。
第二遍:马上自己写一遍,然后提交(切记要根据自己看懂的思路来,而不是真的完全死记硬背)。多种解法比较。
第三遍:第二天重复做昨天的题,增加熟练度。
第四遍:一周后,再次写一遍,增加熟练度。
第五遍:面试前。
差不多就是这五步,当然时间不一定要这么精确,最重要是要多刷。至于为什么第一遍10分钟没思路就马上看题解呢?我认为我们写题并不是创造算法,所以如果不会还是老老实实的去看题解,不要死磕,否则效率会很低,如果有时间可以多想想也不错。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_44713772/article/details/115870745

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云轻量应用服务器和云服务器ECS有什么区别?

阿里云服务器ECS和轻量应用服务器有什么区别&#xff1f;轻量和ECS优缺点对比&#xff0c;云服务器ECS是明星级云产品&#xff0c;适合企业专业级的使用场景&#xff0c;轻量应用服务器是在ECS的基础上推出的轻量级云服务器&#xff0c;适合个人开发者单机应用访问量不高的网站…

dash 初体验(拔草)

Dash简介 Dash 是一个高效简洁的 Python 框架&#xff0c;建立在 Flask、Poltly.js 以及 React.js 的基础上&#xff0c;设计之初是为了帮助前端知识匮乏的数据分析人员&#xff0c;以纯 Python 编程的方式快速开发出交互式的数据可视化 web 应用。 搭建环境 在学习 Dash 的…

算法之美:数据结构之二叉树

平时写业务代码的时候很少写对应的算法&#xff0c;因为很少会在内存中存储大量数据&#xff0c;在需要比较大量数据的查找时&#xff0c;多会依赖的中间件&#xff0c;而中间件底层就应用了很多不同算法&#xff0c;尤其是树结构的查找存储算法&#xff0c;二分查找算法在树里…

把 Taro 项目作为一个完整分包,Taro项目里分包的样式丢失

现象&#xff1a; 当我们把 Taro 项目作为原生微信小程序一个完整分包时&#xff0c;Taro项目里分包的样式丢失&#xff0c;示意图如下&#xff1a; 原因&#xff1a; 在node_modules/tarojs/plugin-indie/dist/index.js文件里&#xff0c;限制了只有pages目录下会被引入app.w…

C# WPF编程-事件

C# WPF编程-路由事件 路由事件概要路由事件的三种方式 WPF事件WPF最重要的5类事件&#xff1a;生命周期事件 鼠标事件键盘事件多点触控输入原始触控 路由事件概要 路由事件是具有更强传播能力的事件&#xff0c;它们可在元素树中向上冒泡和向下隧道传播&#xff0c;并沿着传播…

稀碎从零算法笔记Day21-LeetCode:单词规律

题型&#xff1a;哈希表、字符串 链接&#xff1a;290. 单词规律 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给定一种规律 pattern 和一个字符串 s &#xff0c;判断 s 是否遵循相同的规律。 这里的 遵循 指完全匹配&#xff0c;例如&am…

uni-app从零开始快速入门

教程介绍 跨端框架uni-app作为新起之秀&#xff0c;在不到两年的时间内&#xff0c;迅速被广大开发者青睐和推崇&#xff0c;得益于它颠覆性的优势“快”&#xff0c;快到可以节省7套代码。本课程由uni-app开发者团队成员亲授&#xff0c;带领大家无障碍快速掌握完整的uni-app…

QT文件读写操作和内容提取

访问IO设备&#xff0c;需要先调用open()来设置正确的OpenMode(例如ReadOnly或ReadWrite) 打开设备后后&#xff0c;使用write() 或putChar() 写入数据到文件和设备&#xff0c;并通过调用read()&#xff0c;readLine() 或readAll() 进行读取&#xff1b;使用完设备后&#xf…

机器学习——决策树剪枝算法

机器学习——决策树剪枝算法 决策树是一种常用的机器学习模型&#xff0c;它能够根据数据特征的不同进行分类或回归。在决策树的构建过程中&#xff0c;剪枝算法是为了防止过拟合&#xff0c;提高模型的泛化能力而提出的重要技术。本篇博客将介绍剪枝处理的概念、预剪枝和后剪…

代码随想录算法训练营第二十四天| 回溯算法理论基础、LeetCode77. 组合

# 回溯算法理论基础 # Backtracking 理论基础视频讲解&#xff1a;带你学透回溯算法&#xff08;理论篇&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili #LeetCode 77. Combinations #LeetCode 77. 视频讲解&#xff1a;带你学透回溯算法-组合问题&#xff08;对应力…

力扣爆刷第103天之CodeTop100五连刷1-5

力扣爆刷第103天之CodeTop100五连刷1-5 文章目录 力扣爆刷第103天之CodeTop100五连刷1-5一、3. 无重复字符的最长子串二、206. 反转链表三、146. LRU 缓存四、215. 数组中的第K个最大元素五、25. K 个一组翻转链表 一、3. 无重复字符的最长子串 题目链接&#xff1a;https://l…

Oracle数据库如果出现乱码,需要查看是否时字符集不一致导致乱码,这样解决

1、如果出现乱码&#xff0c;需要查看是否时字符集不一致导致乱码 以修改为ZHS16GBK字符集为例&#xff0c;具体字符集需要sql查询。 Oracle查看字符集 SELECT * FROM NLS_DATABASE_PARAMETERS p where p.PARAMETERNLS_CHARACTERSET; SELECT USERENV(language) FROM DUAL; 1.…

谷歌seo营销服务有哪些服务?

以我们举例&#xff0c;如果你在做B2B外贸建站&#xff0c;这里有全套保姆式托管服务&#xff0c;让你既省心又省力&#xff0c;七天就能搞定网站建设&#xff0c;快速上线&#xff0c;再来就是谷歌白帽SEO&#xff0c;我们这边强调的是纯白帽操作&#xff0c;专注于高质量的原…

Cmake和opencv环境安装

1 Cmake下载及安装 Download CMake 根据需要下载&#xff0c;历史版本下载方法如下 CMake 的版本号中的后缀 "rc1" 和 "rc2" 表示 Release Candidate 1 和 Release Candidate 2&#xff0c;它们都是候选版本&#xff0c;用于测试新功能和修复 bug。通常情…

uni-app里面如何使用图标

目录 一、导入 1.在官方&#xff08;iconfont-阿里巴巴矢量图标库&#xff09;选择自己想要的图标&#xff0c;加入购物车 2. 在点击购物车下载代码 3.解压文件夹 并更改名字 4.将文件夹&#xff08;iconfont&#xff09;整个放到项目中的static中 5.修改iconfont.css文件…

ctfshow-web入门-反序列化

web254 先看题 <?php/* # -*- coding: utf-8 -*- # Author: h1xa # Date: 2020-12-02 17:44:47 # Last Modified by: h1xa # Last Modified time: 2020-12-02 19:29:02 # email: h1xactfer.com # link: https://ctfer.com*/error_reporting(0); highlight_file(__FIL…

系统架构设计-构建系统应用

1. 系统架构目标与设计原则 在设计系统架构时&#xff0c;我们的目标是确保系统具有以下特点&#xff1a; 可靠性&#xff1a;系统能够持续稳定运行&#xff0c;保证业务可用性。可伸缩性&#xff1a;系统能够根据负载变化自动扩展或收缩&#xff0c;以应对不同的流量需求。容…

string类的详细模拟实现

string类的模拟实现 文章目录 string类的模拟实现前言1. 类的框架设计2. 构造函数与析构函数3. 拷贝构造与重载赋值运算符函数4. 运算符重载5. 成员函数6. 迭代器的实现7. 非成员函数8. 单元测试总结 前言 ​ 在现代编程中&#xff0c;字符串处理是每个程序员都会遇到的基本任…

Web核心简介

简介 web&#xff1a;全球广域网&#xff0c;也称万维网(www)&#xff0c;能够通过浏览器访问的网站 JavaWeb&#xff1a;是用Java技术来解决相关web互联网领域的技术栈 JavaWeb技术栈 B/S架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式&#xff0c;它的…

精神暴力的来源与解药

导致人生病的&#xff0c;不仅是病毒或细菌&#xff0c;也有精神暴力。与病毒破坏物理肌体、摧毁生命不同&#xff0c;精神暴力是让人们在过度的自我狂热中燃尽自我、而毁灭自身的。 21世纪以来&#xff0c;精神方面的疾病越来越多&#xff0c;为什么这样呢&#xff1f;大的背景…