直方图中最大矩形面积

Largest Rectangle in Histogram 直方图中最大矩形面积

一个直方图是由许多矩形组成,在给定的直方图中找出最大的矩形面积。为了简化问题,假定所有矩形宽度都为1个单位。

例如,下面的直方图中有7个矩形,高度分别是(6,2,5,4,5,2,6)。最大的矩形面积是12(如下图所示,最大矩形面积用红色方框标出)

下面给出的解决方法时间复杂度为O(n)。矩形面积的计算公式为底*高。对于直方图中的每个矩形’x’(例如图中高度为6,2或5的矩形)以该矩形的高度为高(因为在直方图中最大矩形的高必然是某个单独矩形高),然后计算出最大矩形面积。因此接下来的问题是,若以某个矩形的高度为高,那么最终矩形的左边界和右边界在哪里?确定两个边界后就可以得到宽度,最终计算出面积。

我们从左向右遍历每个矩形,并通过一个栈来存储这些矩形高度在输入数组中的索引。每个矩形(索引)仅压入栈中一次。当输入的矩形高度小于栈顶矩形的高度,那么栈顶矩形将会被弹出,然后计算矩形面积,其中矩形面积的高为弹出单个矩形条的高。现在得到了高,接下来得到左右边界后便可计算出宽度。由于当前输入的矩形i的高度小于栈顶矩形,那么以栈顶为高的矩形右边界为i。而在当前栈中若非空,那么栈中矩形条的高度一定是小于等于弹出的矩形的高度,因此左边界就确定了。(当有多个连续的高度一样的矩形条时,计算最后一个出栈的矩形时会得到最终的面积)

最终算法步骤归纳为:

  1. 创建一个空栈
  2. 从第一个矩形条开始,对每个矩形条的高度height[i] (i的取值范围是[0,n-1])执行下面两步 
    a) 如果栈为空,或height[i]大于等于栈顶元素,那么将矩形条i压入栈中。 
    b)如果输入的矩形条高度小于栈顶元素高度,那么将栈顶元素在输入数组中的索引tp出栈,然后计算矩形面积。矩形的高为height[tp],而右边界为i,左边界为当前栈顶元素对应的索引,若栈为空,则宽度就是i。
  3. 经过计算后,栈非空,然后将栈中元素逐个弹出,并按照步骤2计算矩形面积,并且更新最大值。

总结:若输入序列是是升序,那么依次入栈,让入栈元素小于栈顶,以栈顶元素为高的矩形左边界必然是将高出栈后新的栈顶元素的位置(因为是按升序入栈)。而栈中元素是按升序排列那么以栈中任意一个元素为高,必然可以和栈顶元素构成矩形,所以当即将入栈元素小于栈顶元素时,那么右边界即是这个入栈元素的索引位置。

下面是Java的实现代码。

public class Solution {
    public int largestRectangleArea(int[] height) {
        Stack<Integer> s = new Stack<>();
        int max_area = 0; // 最大矩形面积
        int tp; // 栈顶
        int area_with_top;

        int i = 0;
        int n = height.length;
        while (i < n) {
            if (s.empty() || height[s.peek()] <= height[i]) {
                s.push(i++);
            } else {
                tp = s.pop();
                area_with_top = height[tp] * (s.empty() ? i : i - s.peek() - 1);
                max_area = Math.max(max_area, area_with_top);
            }
        }

        while (!s.empty()) {
            tp = s.pop();
            area_with_top = height[tp] * (s.empty() ? i : i - s.peek() - 1);
            max_area = Math.max(max_area, area_with_top);
        }
        return max_area;
    }
}

本文转自博客园知识天地的博客,原文链接:直方图中最大矩形面积,如需转载请自行联系原博主。

时间: 2024-10-13 00:01:53

直方图中最大矩形面积的相关文章

庞果网之寻找直方图中面积最大的矩形

题目详情 给定直方图,每一小块的height由N个非负整数所确定,每一小块的width都为1,请找出直方图中面积最大的矩形.    如下图所示,直方图中每一块的宽度都是1,每一块给定的高度分别是[2,1,5,6,2,3]:    那么上述直方图中,面积最大的矩形便是下图所示的阴影部分的面积,面积= 10单位.    请完成函数largestRectangleArea,实现寻找直方图中面积最大的矩形的功能,如当给定直方图各小块的高度= [2,1,5,6,2,3] ,返回10. [解析] 使用一个栈

[算法]CSDN编程挑战赛之寻找直方图中面积最大的矩形

继续看挑战赛的算法,虽然不指望能得到什么奖项,但能够将自己的思想用程序表达出来就是一种乐趣! 请看题: 我的解题思路: 就是判断[i,i+1,i+2...j]之间的最小高度H,然后通过s=(j-i+1)*H来计算面积,然后筛选出最大的面积. C++代码: //寻找直方图中面积最大的矩形 #include <cstdio> #include <cstring> #include <string> #include <vector> #include <s

面向对象编程方式实现四则运算和计算矩形面积

用Javascript实现类似两个选项卡切换的效果,用面向对象编程的方式,实现四则运算和计算矩形面积: CatView.php: <html> <head> <meta http-equiv="content-type" content="text/html;charset=GBK" /> <script language="javascript"> <!-- function selType

SQL Server 中统计信息直方图中对于没有覆盖到谓词预估以及预估策略的变化(SQL2012--&gt;SQL2014--&gt;SQL2016)

原文:SQL Server 中统计信息直方图中对于没有覆盖到谓词预估以及预估策略的变化(SQL2012-->SQL2014-->SQL2016)   本文出处:http://www.cnblogs.com/wy123/p/6770258.html    统计信息写过几篇了相关的文章了,感觉还是不过瘾,关于统计信息的问题,最近又踩坑了,该问题虽然不算很常见,但也比较有意思.相对SQL Server 2012,发现在新的SQL Server版本(2014,2016)中都有一些明显的变化,下文将对此

jquery-如何把如下的代码中的矩形标签形状改成五角星的形状

问题描述 如何把如下的代码中的矩形标签形状改成五角星的形状 <!doctype html> jquery多彩标签云选择效果 ul,li{list-style:none;padding:0px;margin:0px} ul.cloud{zoom:1;overflow:hidden;width:300px} ul.cloud li{-moz-border-radius:6px;-webkit-border-radius:6px;background:#fff;border:solid 1px pu

ArcGIS平台,使用Engine,现在MapControl中拉出一个矩形框,如何将此矩形框内的各要素层加入到PageLayout Control中(矩形框

问题描述 ArcGIS平台,使用Engine,现在MapControl中拉出一个矩形框,如何将此矩形框内的各要素层加入到PageLayoutControl中(矩形框外的要素不被加入),有没有一个简洁的方法呢?做了好长时间,还是不行,请各位帮忙? 解决方案 解决方案二:怎么没有同行回复呢解决方案三:空间分析,SearchbyRect解决方案四:我已经解决了解决方案五:怎么解决的,楼主共享一下啊

Raptor实践参考:求矩形面积

返回->课程主页 1-2 求矩形面积 输入矩形的长和宽,计算并输出矩形的面积 [参考解答]

Raptor实践参考:求矩形面积的过程

返回->课程主页 1-3 求矩形面积的过程 输入矩形的长和宽,计算并输出矩形的面积.要求将求面积的功能定义为一个过程. [参考解答]

POJ 2082(最大连续矩形面积)

Terrible Sets Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 2428   Accepted: 1215 Description Let N be the set of all natural numbers {0 , 1 , 2 , . . . }, and R be the set of all real numbers. wi, hi for i = 1 . . . n are some element