题目如下:(https://leetcode.com/problems/largest-rectangle-in-histogram/)

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

        

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given height = [2,1,5,6,2,3],
return 10.

题目似乎很简单,只要求出直方图中最大的矩形面积即可。然而最最单纯的O(n2)算法显然会跪(别人试过,我就不作死了……)。

有两类思路,分别如下:

Part One

提示说用栈,然而并没有想出如何使用。看懂别人的思路后再写,总觉得略微无聊……还是在此用自己的话复述一下吧。

(以下所有图片来自http://blog.csdn.net/doc_sgl/article/details/11805519

题目要求需要找面积最大的矩形,这个矩形的高为直方图中某柱高,我们可以认为矩形是由一个柱向两侧扩展得到的。

题中的直方图可以形象地理解为“波”,在一个波峰附近第一个高度下降的柱(下图中的t)会限制其左侧比它高的柱(记某柱为z)形成矩形的宽度,又由于t是该波峰第一个下降的柱形,故左侧比它高的柱z形成的矩形宽度为t与z横坐标之差(由于后续操作形成的波并不是连续的柱,此处实际上应为t-z前一个柱横坐标-1),这样就得到了一个矩形面积。

如上操作后,柱z已经完成了它的使命(已经求出由它形成的矩形的面积,左右的矮柱也不需要它的高度),当t左侧所有高柱都完成使命后,t成了相对高的柱,可以看作与前面的更矮的柱又在形成一个又矮又宽的波峰(图中阴影),遇到更矮的i之后,重复前面的操作即可得到所有柱生成的矩形的面积。

于是,我们可以用栈保存一串连续上升的柱(波上升的部分),当遇到矮柱时,求前面每个高柱形成的矩形的面积,然后将这个没用的高柱弹出。最后将矮柱压入,作为下一个波的上升部分。这个过程扫描一遍,算法复杂度为O(n)。

/************************如果觉得上面写的清晰可以忽略下面的部分**************************/

针对样例输入,可以进行如下分析:

1.将柱0压栈,。

2.柱1更矮,求柱0形成的矩形面积,将柱1压栈。

3.柱1柱2柱3高度递增,进栈。

4.柱4比2,3矮:柱3求面积,出栈;柱2求面积,出栈。

5.柱4柱5进栈。

6.最后求栈中剩余柱形成矩形的面积(相当于最后有一个高度为0的柱,使其前面的柱出栈)。

(似乎应该在这里再说一下,以上所有图片来自http://blog.csdn.net/doc_sgl/article/details/11805519 )//2015/11/13日补

/************************懂了上面,下面的代码其实不重要了**************************/

class Solution {
public:
int largestRectangleArea(vector<int>& height) { height.push_back(); //使最后栈中剩余柱出栈
stack<int> serHeight; //储存高度递增的柱的栈
int maxArea = ; //最大面积
int curArea = ; //当前矩形面积 for (int i = ; i < height.size(); i++)
{
if (serHeight.empty() || height[serHeight.top()] <= height[i]) //高度上升,进栈
{
serHeight.push(i);
}
else
{
//将高矩形出栈,求其生成的矩形面积
while (height[serHeight.top()] > height[i])
{
int cur = serHeight.top();
serHeight.pop();
if (serHeight.empty())
{
curArea = height[cur] * i;
maxArea = (maxArea > curArea) ? maxArea : curArea;
break;
}
curArea = height[cur] * (i - serHeight.top() - );
maxArea = (maxArea > curArea) ? maxArea : curArea;
} serHeight.push(i);
}
}
return maxArea;
}
};

Part Two

一个更容易想到的思路是先判断每个柱左右两边不比它矮的最远柱,然后可以更容易地算出由当前柱形成的矩形面积。

利用动态规划的思想,可以利用前面已确定的最远高柱更新当前需要找的柱。比如下面代码中若l[i]左边的l[i]-1比i还要高,那么可以用l[l[i] - 1]更新l[i],这样可以加快查找高柱的速度。

class Solution {
public:
int largestRectangleArea(vector<int>& height) {
int maxArea = ; //最大面积
int curArea = ; //当前面积
int s = height.size(); //柱形个数
int *l = new int[s]; //储存不比当前柱矮的最左端柱
int *r = new int[s]; //储存不比当前柱矮的最右端柱 //先找储存不比当前柱矮的最左端柱
for (int i = ; i < s; i++)
{
l[i] = i; //自己不比自己矮
//利用已存过的l[i]判断是否找到最左端
while (l[i] && height[l[i] - ] >= height[i])
{
l[i] = l[l[i] - ];
}
}
//再找储存不比当前柱矮的最右端柱
for (int i = s - ; i >= ; i--)
{
r[i] = i;
while ((r[i] - s + ) && height[r[i] + ] >= height[i])
{
r[i] = r[r[i] + ];
}
}
//计算由当前柱生成的矩形面积,更新最大面积
for (int i = ; i < s; i++)
{
curArea = height[i] * (r[i] - l[i] +);
maxArea = (maxArea > curArea) ? maxArea : curArea;
} return maxArea;
}
}

附:

日常膜:http://www.cnblogs.com/lustralisk/p/branch-3.html

生日快乐:http://blog.sina.com.cn/s/blog_1495db3970102w3f8.html

 

 

数据结构与算法(1)支线任务3——Largest Rectangle in Histogram的更多相关文章

  1. LeetCode 笔记系列 17 Largest Rectangle in Histogram

    题目: Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar he ...

  2. 【LeetCode】84. Largest Rectangle in Histogram

    Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...

  3. Maximal Rectangle&Largest Rectangle in Histogram

    这两天在做leetcode的题目,最大矩形的题目以前遇到很多次了,一直都是用最笨的方法,扫描每个柱子,变换宽度,计算矩形面积,一直都以为就这样O(n2)的方法了,没有想到居然还有研究出了O(n)的算法 ...

  4. Largest Rectangle in Histogram及二维解法

    昨天看岛娘直播解题,看到很经典的一题Largest Rectangle in Histogram 题目地址:https://leetcode.com/problems/largest-rectangl ...

  5. 47. Largest Rectangle in Histogram && Maximal Rectangle

    Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...

  6. leetcode Largest Rectangle in Histogram 单调栈

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4052343.html 题目链接 leetcode Largest Rectangle in ...

  7. 关于LeetCode的Largest Rectangle in Histogram的低级解法

    在某篇博客见到的Largest Rectangle in Histogram的题目,感觉蛮好玩的,于是想呀想呀,怎么求解呢? 还是先把题目贴上来吧 题目写的很直观,就是找直方图的最大矩形面积,不知道是 ...

  8. leetcode之Largest Rectangle in Histogram

    问题来源:Largest Rectangle in Histogram 问题描述:给定一个长度为n的直方图,我们可以在直方图高低不同的长方形之间画一个更大的长方形,求该长方形的最大面积.例如,给定下述 ...

  9. LeetCode之“动态规划”:Maximal Square && Largest Rectangle in Histogram && Maximal Rectangle

    1. Maximal Square 题目链接 题目要求: Given a 2D binary matrix filled with 0's and 1's, find the largest squa ...

随机推荐

  1. Python学习-day2

    这周时间充裕,把第一周的两个作业登陆验证和三级菜单做完后又用零零散散的时间看完了第二周的课程,不得不说老男孩这个教育方式感觉还是不错的,其实说白了就是花钱找个人监督自己学习呗,而且还强行让我们养成一些 ...

  2. LintCode Palindrome Partitioning II

    Given a string s, cut s into some substrings such that every substring is a palindrome. Return the m ...

  3. HDFS的运行原理

    简介 HDFS(Hadoop Distributed File System )Hadoop分布式文件系统.是根据google发表的论文翻版的.论文为GFS(Google File System)Go ...

  4. Joomla及其类似软件的说明分析

    Joomla不单单是一款免费的软件,还是在国外相当知名的及内容管理.web开发及手机应用开发等为一体的一套系统.Joomla是使用PHP语言加上MySQL数据库所开发的软件系统,可以在Linux. W ...

  5. PE文件格式 持续更新ing

    PE文件就是exe文件和dll文件,前者是可执行文件,后者是动态连接库文件.两者的区别仅仅是字面上的,唯一的区别就是内部的一个字段标识这个文件是exe文件还是dll文件. 对于PE文件格式,举一个例子 ...

  6. java的三大框架(三)---Hibernate

    一.什么是映射 这里所说的映射就是对象关系映射:将对象数据保存到数据库中,同时可以将数据库数据读入对象中,开发人员只对对象进行操作就可以完成对数据库数据的操作. 二.什么是基本映射 知道了什么是映射, ...

  7. Oracle启动脚本,开机自启动设置

    #!/bin/sh # chkconfig: # description: Oracle auto start-stop script. # # Set ORA_HOME to be equivale ...

  8. JS-学习-DOM元素尺寸和位置

    一,获取元素的css大小 1.通过style内联获取元素的大小 var box = document.getElementById('box');    // 获得元素;     box.style. ...

  9. Nginx 配置 HTTP 强缓存

    server { listen 80; server_name tirion.me www.tirion.me; # note that these lines are originally from ...

  10. Android 中算法问题

    1:冒泡排序: 冒泡排序的思路: 相邻的两个数进行比较 (1):首先需要连个for 循环 (2):最外层for 循环控制最里面 for 循环的循环次数 (3):通过设置中间参数的方式进行交换 (4): ...