问题描述

给一个直方图,求直方图中的最大矩形的面积。例如,下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1, 3, 3, 他们的宽都是1,其中最大的矩形是阴影部分。

Input
输入包含多组数据。每组数据用一个整数n来表示直方图中小矩形的个数,你可以假定1 <= n <= 100000. 然后接下来n个整数h1, …, hn, 满足 0 <= hi <= 1000000000. 这些数字表示直方图中从左到右每个小矩形的高度,每个小矩形的宽度为1。 测试数据以0结尾。
Output
对于每组测试数据输出一行一个整数表示答案。
Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
Sample Output
8
4000

问题分析

单调栈

单调栈 = 栈内元素 自栈顶到栈底 满足 单调性
模拟单调递增栈的操作
现有一数组 [10, 3, 7, 4, 12],从左到右依次入栈。
如果栈为 或者栈顶元素 大于 入栈元素,则入栈。
否则,入栈则会破坏栈内元素的单调性,则需要将不满足条 件的栈顶元素全部弹出后,将入栈元素入栈。
具体过程
10 入栈时, 栈空, 入栈
3 入栈时, 栈顶元素 10 大于 3, 入栈
7入栈时, 栈顶元素 3 小于 7, 弹栈; 栈顶元素 10 大于 7, 入栈
4 入栈时, 栈顶元素 7 大于 4, 入栈
12 入栈时, 栈顶元素 4 小于 12, 弹栈; 栈顶元素 7 小于 12, 弹栈; 栈顶元素 10 小于 12, 弹栈; 栈空, 入栈

解题思路

要找最大矩形面积,即要从当前矩形向左向右分别寻找不小于当前高度的距离。

按照这个思路,如果使用单调栈的话,我们就可以只需要从左至右一遍,然后从由右至左来一遍,分别找出每个点的最右距离和最左距离,只需要遍历两次就可以计算出每个点的最大矩形面积,时间复杂度为O(n)。

因为我们要找出第一个 小于 当前高度的矩形,因此我们选择维护单调递增栈。从1到n遍历,只有当此时遍历到的点的大小大于单调栈顶时,才能加入到单调栈中;若小于栈顶,则栈顶循环弹出,直到栈顶的大小小于此时的点的高度。对于那些被弹出的点,他们对应的最右元素就是此时遍历到的点。
当倒序遍历时,最左元素是此时遍历到的点。

代码实现

#include<stdio.h>
#include<stack>
#include<math.h>
#define N 100050
using namespace std;
//数据类型long long,否则会WA
int n =0;
long long int a[N], L[N], R[N];
stack<int> s;int main()
{scanf("%d",&n);while( n != 0){for(int i=1; i<=n; i++)scanf("%lld",&a[i]);long long int ans=0;R[n] = n;L[1] = 1;for(int i=1; i<=n; i++){while(!s.empty() && a[s.top()] > a[i]){// 栈首的下标temp对应的元素大于当前元素,说明temp的最右元素就是当前元素。int temp = s.top();s.pop();R[temp] = i-1;}s.push(i);}while(!s.empty()){R[s.top()] = n;s.pop();}for(int i=n; i>0; i--){while(!s.empty() && a[s.top()] > a[i]){int temp = s.top();s.pop();L[temp] = i+1;}s.push(i);}while(!s.empty()){L[s.top()] = 1;s.pop();}for(int i=1; i<=n; i++){int len = R[i] - L[i] + 1;long long int sur = len * a[i];if(sur > ans) ans = sur;}printf("%lld\n", ans);scanf("%d",&n);}return 0;}

最大矩形面积——单调栈相关推荐

  1. POJ 2559 题解 最大矩形面积 单调栈

    [题目描述]: 地面上从左到右并排紧挨着摆放多个矩形,已知这此矩形的底边宽度都为1,高度不完全相等.求在这些矩形包括的范围内能得到的面积最大的矩形,打印出该面积.所求矩形可以横跨多个矩形,但不能超出原 ...

  2. LeetCode--85.最大矩形(单调栈)

    最大矩形(单调栈) 1. 题目描述 2. 题目分析 3. C语言实现 1. 题目描述 难度:困难 2. 题目分析 这道题目似曾相识啊,最大矩形面积的问题我们在LeetCode84.柱状图中最大的矩形也 ...

  3. leetcode 1504. Count Submatrices With All Ones | 1504. 统计全 1 子矩形(单调栈)

    题目 https://leetcode.com/problems/count-submatrices-with-all-ones/ 题解 本题与 leetcode 84. Largest Rectan ...

  4. leetcode 85. Maximal Rectangle | 85. 最大矩形(单调栈)

    题目 https://leetcode.com/problems/maximal-rectangle/ 题解 本题与 leetcode 84. Largest Rectangle in Histogr ...

  5. [Leedcode][JAVA][第84题][柱状图中最大的矩形][暴力][单调栈]

    [问题描述][困难] 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 .求在该柱状图中,能够勾勒出来的矩形的最大面积.以上是柱状图的示例,其中每个柱子的宽度为 1 ...

  6. 直方图中最大的矩形(单调栈2)

    题目描述 直方图是由在公共基线处对齐的一系列矩形组成的多边形. 矩形具有相等的宽度,但可以具有不同的高度. 例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1: ...

  7. 【CSP201312-3】最大的矩形,单调栈

    problem 201312-3 试题名称: 最大的矩形 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ ...

  8. 最大矩形(单调栈 || 动态规划)

    文章目录 问题描述 Input Output Sample input Sample output 思考 解题思路--单调栈做法 单调栈介绍 单调栈在此题中的应用 完整代码--单调栈 解题思路--动态 ...

  9. leetcode 84. Largest Rectangle in Histogram | 84. 柱状图中最大的矩形(单调栈)

    题目 https://leetcode.com/problems/largest-rectangle-in-histogram/ 题解 一句话总结:遍历数组,对于每个height[i],以其自身的高度 ...

最新文章

  1. 配置基于Devstack的嵌套KVM虚拟化
  2. linux存储--inode详解(六)
  3. 会计信息质量要求有哪些?
  4. python traceback class_traceback:让你更加灵活地处理python的异常
  5. Linux系统优势六大方面
  6. 如何避免Puppeteer被前端JS检测
  7. 信息学奥赛一本通(1228:书架)
  8. pytorch1.7教程实验——分类器训练
  9. [Swift]扩展String类:实现find()查找子字符串在父字符串中的位置
  10. 【Kafka】Kafka 镜像 Kafka mirroring (MirrorMaker)
  11. 施耐德电气的 Modicon PLC 中被曝严重漏洞,已有缓解措施
  12. web 网站抢购并发
  13. 学Java编程可以做什么?发展方向有哪些?
  14. 如何加减单元格指定数字_表格怎么自动计算加减
  15. 大话西游2人数最多服务器,逆生长!126万玩家再造【大话西游2】“火爆现象”...
  16. html 调用es2015模块,现在,在项目中直接部署ES2015+代码吧!
  17. 【软件工程】产品调研分析报告
  18. WIFI信号放大增强器(中继器)中继成功后怎么改名字
  19. 第二十次csp认证 第四题 星际旅行题解
  20. 通过bat批处理命令进行adb push批量拉取文件

热门文章

  1. 【日精进】2017-12-22 天气:晴
  2. linux 读取 文件前缀,linux 取文件前缀名
  3. 怎么下载在阿里云平台注册域名的域名证书
  4. 悟空CRM项目实战(6)
  5. 不需要网络的调频收音机_在过去的15年,短波台相继停播,现在买这样的收音机还有什么用...
  6. mac怎么关闭自启动项
  7. U盘提示磁盘结构损坏且无法读取怎么办?
  8. Kinect体感互动解决方案——体感蹦床互动游戏
  9. JAVA——迷宫问题
  10. 28、最小的k个数(TopK)