给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例:

输入: [2,1,5,6,2,3]
输出: 10

来源:力扣(LeetCode)


首先肯定暴力啊,思想:矩形有长宽啊,暴力枚举。。。wa在了最后一个样例(样例个数超1W)

class Solution {public:int largestRectangleArea(vector<int>& heights) {int ans=0;int wid=0;int tep=0;for(auto hei:heights){//矩形长for(auto cn:heights){if(hei<=cn){wid++;//矩形宽tep=hei*wid;}else{ans=max(ans,tep);tep=0;wid=0;}   }ans=max(ans,tep);tep=0;wid=0;}return  ans;}
};

分治法,
1.确定了最矮柱子以后,矩形的宽尽可能往两边延伸。
2.在最矮柱子左边的最大面积矩形(子问题)。
3.在最矮柱子右边的最大面积矩形(子问题)。

class Solution {public:int calculate(vector<int>&heights,int start,int end){if(start>end) return 0;int mini=start;for(int i=start;i<=end;i++){if(heights[mini]>heights[i]){ mini=i;}}return max(heights[mini]*(end-start+1),max(calculate(heights,start,mini-1),calculate(heights,mini+1,end)));}int largestRectangleArea(vector<int>& heights) {return calculate(heights,0,heights.size()-1);}
};

当时还用minH=0x3f3f3f3f,没想到有个样例是int的最大范围,这个说明一定要谨慎。平均O(nlogn),最坏O(n^2).


看了一下大佬的思想。
以第i根柱子为最矮柱子所能延伸的最大面积。具体就是找出第i根柱子左边第一个小于heights【i】的下标left_i;右边也是,找出第一个小于heights【i】的下标right_i,则面积是heights【i】*(right_i - left_i -1)
剩下的就是如何高效的找出这两个数组了。
1.如果heights【i-1】>=heights【i】,那么问题转化为找出第i-1柱子左边的柱子。

//遍历左边
for(i from 0 to heights.size(){int tmp=i-1;while(heights[i-1]>=heights[i]) tmp=left_i[tmp];left_i[i]=tmp;
)
//在添加一些边界即可。

总体代码

class Solution {public:int largestRectangleArea(vector<int>& heights) {if(heights.empty()) return 0;//力扣上数组长度可能为0int size=heights.size();int  left_i[size+1];int right_i[size+1];left_i[0]=-1;right_i[size-1]=size;for(int i=1;i<size;i++){int tmp=i-1;while(tmp>=0&&heights[tmp]>=heights[i]) tmp=left_i[tmp];left_i[i]=tmp;}for(int i=size-2;i>=0;i--){int tmp=i+1;while(tmp<size&&heights[tmp]>=heights[i]) tmp=right_i[tmp];right_i[i]=tmp;}int ans=0;for(int i=0;i<size;i++){ans=max(ans,heights[i]*(right_i[i]-left_i[i]-1));}return ans;}
};
  1. 单调栈
    栈里面的元素是递增的。保存的是矩形的下标。

当柱子的高度递增时,入栈柱子的下标。
当出现柱子(i)的高度小于栈顶时(右边第一个高度小于他的矩形),可以套公式计算了。
right_i=i, left_i =弹出栈之后的栈顶(栈里面是递增的,弹出栈之后,找到了左边第一个小于他的矩形),高度=heights[ 当前栈顶]。
遍历完了之后,栈里面可能还有元素。这时要注意 right_i 始终等于= heights.size()了。

class Solution {public:int largestRectangleArea(vector<int>& heights) {stack<int>st;st.push(-1);int size=heights.size();int ans=0;for(int i=0;i<size;i++){while(st.top()!=-1&&heights[i]<heights[st.top()]){int top=st.top();st.pop();ans=max(ans,heights[top]*(i-1-st.top()));}st.push(i);}while(st.top()!=-1){int top=st.top();st.pop();ans=max(ans,heights[top]*(size-1-st.top()));}return ans;}
};

不得不说这个-1和size真是太妙了!!

84.柱形图中最大的矩形相关推荐

  1. 二维矩阵中的最大矩形面积--java实现

    一.原题: 给你一个二维矩阵,权值为False和True,找到一个最大的矩形,使得里面的值全部为True,输出它的面积. 样例: 给你一个矩阵如下: [[1, 1, 0, 0, 1],[0, 1, 0 ...

  2. python在坐标轴上画矩形_Python使用matplotlib实现在坐标系中画一个矩形的方法

    本文实例讲述了Python使用matplotlib实现在坐标系中画一个矩形的方法.分享给大家供大家参考.具体实现方法如下: import matplotlib.pyplot as plt from m ...

  3. OpenCV中绘制外围矩形框和圆框

    OpenCV中绘制外围矩形框和圆框 利用边界寻找函数找到的边界坐标信息.然后利用每一条寻找到的边际信息去找到图形的矩形边界和圆形边界. 一. OpenCV中绘制外围矩形框 根据已知的边界信息点.将边界 ...

  4. HTML设置单边圆角,如何在html中做圆角矩形和 只有右边的分隔线

    其实是对(理论上是对所有的)html元素: 而实际 常用的是 div块, 链接a 等运用圆角矩形的样式 这个圆角是通过元素: div, a的 css 样式来实现的: 样式: border-radius ...

  5. 如何在html中做圆角矩形和 只有右边的分隔线

    这个网站满好的,可以常看看 css-matic中有几个很好的写css可视化的工具 其实做css 版式布局等都可以有工具的 推荐40个优秀的免费CSS工具 debugger正则表达式在线 其实是对(理论 ...

  6. 【教程】PDF开发工具Spire.PDF 教程:使用C#从PDF中的特定矩形区域中提取文本

    Spire.PDF 是一个专业的PDF组件,能够独立地创建.编写.编辑.操作和阅读PDF文件,支持 .NET.WPF和Silverlight三个版本,本文介绍了如何通过Spire.PDF使用C#从PD ...

  7. 怎样在matlab中写技术,rect矩形函数 matlab中怎样编写矩形函数

    矩形函数的定义: 矩形函数 rect(t); 如果绝对值 |t| > 0.5 rect(t) = 0; 如果绝对值 |t| = 0.5 rect(t) = 0.5; 如果绝对值 |t| < ...

  8. 在Canvas中绘制圆角矩形

    问题的提出 要在Canvas中绘制一个矩形,使用strokeRect或fillRect函数即可. var canvas = document.getElementById("canvas&q ...

  9. 算法学习——剑指 Offer II 040. 矩阵中最大的矩形(Java实现)

    1. 题意 这是LeetCode上的 [040,矩阵中最大的矩形],难度为 [困难] 2. 思路分析 这道题跟上一题一样还是求最大矩形的面积,所以求最大矩形的面积可以参考直方图的最大矩形面积,那么这道 ...

最新文章

  1. ios开发判断字符串为空_【开发常识】这个问题,直接导致年终奖没了……(惨兮兮)...
  2. JavaScript 技术篇-js正则表达式匹配字符串左右两边是否包含空格
  3. cpu飙升 死循环_java排查一个线上死循环cpu暴涨的过程分析
  4. vcruntime140.dll 丢失64位系统(mysql8安装失败提示)
  5. #1176 : 欧拉路·一(欧拉通路的判定)
  6. win32汇编入门(一)
  7. 电脑桌面便签_在电脑桌面使用敬业签怎么操作退出团队便签?
  8. WINCE Driver 心得总结
  9. iDowns-v1.8.3 无缝对接erphpdown会员中心+在线充值+VIP开通+卡密插件
  10. verilog奇偶分频
  11. 比特币一种点对点的电子现金系统是哪一年诞生的_庆比特币诞生12周年|带你回顾比特币的前世今生...
  12. java简单小程序 生日快乐,微信生日祝福小程序,要一个祝朋友生日快乐的VB小程序。...
  13. PHP中根据汉字返回拼音
  14. DCOS之Mesos-DNS介绍
  15. datacom-HCIP之题库继续解析
  16. 2020年国家扶贫日“三产联动扶贫论坛”在京召开,杭州复杂美科技有限公
  17. PTA 实验7-5 输出大写英文字母(10 分)
  18. VS通过ODBC连接MYSQL(一)
  19. MxNet系列——how_to——new_op
  20. 微信小程序 uChars统计图

热门文章

  1. 【OpenCV 4开发详解】轮廓发现与绘制
  2. 链表问题3——删除链表的中间节点(初阶)
  3. MaxCompute2.0新功能介绍
  4. java创建线程安全的集合
  5. Redis基础、应用、第三方支持组件总结
  6. 高性能server分析 - Hadoop的RpcServer
  7. Linux 高可用(HA)集群之keepalived+lvs
  8. 【三个臭皮匠】第一次网络会议记录
  9. 人民搜索,该怎么说你才好
  10. 去Tech Ed得计划好