原题

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.

示例

Given heights = [2,1,5,6,2,3],
return 10.

解题思路

第一阶段:

拿到这种题,首先想怎么用最暴力的方法解决这个问题,于是自然而然的想出来枚举的方法,即利用二重循环枚举所有可能的区间,接着再这区间中找出最小的值,然后用(最小值 * 区间宽度)求出每个区间的最大值,最后从这些最大值中找出最大解。

这种解法的时间复杂度是O(n^3),一般都会超时的,那么我们就会想着降低时间复杂度,即去冗余的方法(冗余分为重复计算和不需要计算两种)

第二阶段:

那么哪里存在冗余呢?第一个想到的应该是区间内求最小值时存在重复计算,我们可以使用空间换时间的方法将之前算过的最小值存储下来,这样求最小值[i][j] 就等于MIN( 最小值[i][j-1] ,  j) ,这样我们就时间复杂度降低到了O(n^2)

第三阶段:

通过推演又进一步发现了冗余的地方,比方说对于[9, 8, 10, 3, 12, 11,15]来说,虽然我们枚举了所有可能的区间,计算了其区间内的最小值,但你有没有发现,其中大多数的最小值都是 3, 那么我们能不能改变思路减少该冗余呢?

于是乎我们可以采用枚举最小值的算法,即假设每一个点都是最小值,然后我们计算出其作为最小值可以向左右两边延伸的最大区间(如果该点左边的点值大于该点,则继续往左比较,知道某点比该点值小为止)

最后可以算出每一个点作为最小值所包括的最大面积。面积 = n点高度 * (n右边界 - n左边界 + 1 )

第四阶段:

上一阶段的时间复杂度似乎并没有减少,那么肯定这种新思路引来了新的冗余,这种冗余在哪里呢?

我们发现在找一个点的左右最大区间时存在重复计算,因为如果n点比n - 1点的值大的话,那么n点左边界应该大于等于n - 1点的左边界,于是乎我们可以存储下每个点的左右边界,避免很多重复计算

最终思路:

  1. 枚举所有点,将其作为最小值
  2. 记录每个点的左右边界(计算n点左边界的方法是:判断n是否比n - 1小,如果成立则跳到n - 1 点的左边界x, 比较n是否比x小,如此循环,知道求出左边界)
  3. 枚举每一个点的最大面积,计算最大解

完整代码

public class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
if (n == 0) {
return 0;
}
// 求左边的边界
int[] left = new int[n];
left[0] = 0;
for (int i=1;i<n;++i) {
int A = i;
while (A > 0 && heights[A - 1] >= heights[i]) {
A = left[A - 1];
}
left[i] = A;
}
// 求右边的边界
int[] right = new int[n];
right[n - 1] = n - 1;
for (int i=n-2;i>=0;--i) {
int A = i;
while (A < n - 1 && heights[A + 1] >= heights[i]) {
A = right[A + 1];
}
right[i] = A;
}
// 枚举每一个最小值的最大面积
int ans = 0;
for (int i=0;i<n;++i) {
ans = Math.max(ans, heights[i] * (right[i] - left[i] + 1));
}
return ans;
}
}

  

    

LeetCode 84. Largest Rectangle in Histogram 直方图里的最大长方形的更多相关文章

  1. [LeetCode] 84. Largest Rectangle in Histogram 直方图中最大的矩形

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  2. [leetcode]84. Largest Rectangle in Histogram直方图中的最大矩形

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  3. LeetCode 84. Largest Rectangle in Histogram 单调栈应用

    LeetCode 84. Largest Rectangle in Histogram 单调栈应用 leetcode+ 循环数组,求右边第一个大的数字 求一个数组中右边第一个比他大的数(单调栈 Lee ...

  4. 【LeetCode】84. Largest Rectangle in Histogram——直方图最大面积

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  5. leetCode 84.Largest Rectangle in Histogram (最大矩形直方图) 解题思路和方法

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  6. [leetcode]84.Largest Rectangle in Histogram ,O(n)解法剖析

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  7. [LeetCode#84]Largest Rectangle in Histogram

    Problem: Given n non-negative integers representing the histogram's bar height where the width of ea ...

  8. 【LeetCode】84. Largest Rectangle in Histogram 柱状图中最大的矩形(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调栈 日期 题目地址: https://leetc ...

  9. 84. Largest Rectangle in Histogram

    https://www.cnblogs.com/grandyang/p/4322653.html 1.存储一个单调递增的栈 2.如果你不加一个0进去,[1]这种情况就会输出结果0,而不是1 3.单调递 ...

随机推荐

  1. 算法模板——平衡树Treap

    实现功能如下——1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为小于x,且最大 ...

  2. win10环境下jdk1.8+Android Developer Tools Build: v22.3.0-887826的问题

    最进换了新电脑,配置开发环境,最新的android studio 要求jdk1.8,所以想都没想就下载1.8. 之后为了一个原来的老项目,得使用adt,遂装之,遇到一下问题 1.ADT新建项目src下 ...

  3. Socket协议

    Socket协议的形象描述 socket的英文原义是"孔"或"插座".在这里作为4BDS UNIX的进程通信机制,取后一种意思.socket非常类似于电话插座. ...

  4. Mybatis的@Options注解

    mybatis的@Options注解能够设置缓存时间,能够为对象生成自增的key 第一个使用场景: 有一个表 CREATE TABLE instance ( instance_id BIGINT UN ...

  5. ICC_lab总结——ICC_lab1:数据设置和基本流程

    ICC_lab总结 最近在学习后端的流程,做lab是最好不过了.但是有时候做过了lab,过了一段时间之后就会忘记,因此需要自己总结一下,加强印象. ICC_lab1:数据设置和基本流程 数据设置: 一 ...

  6. ThinkPHP数据字段的缓存问题

    在使用ThinkPHP开发应用时,在项目运行后会在应用(Application)目录下产生一个Runtime缓存文件夹 在生成Runtime之后,若改变数据表的字段结构,则在PHP代码中无法为新的字段 ...

  7. 把GIF背景变透明

    准备软件: 1.Ps cs4 2.QuickTime Player 7.74 开始: 1. 2.弹出文件选择框,但是发现不能选择GIF格式. 3.没关系,在文件名框输入*.*回车,就发现可以选择GIF ...

  8. Rsync的工作方式

    Rsync的工作方式(来自网络) 1)拷贝本地文件: 当SRC和DES路径信息中不包含冒号":"分隔符时,就启用这种工作模式: [root@cmmailapp1 /]# rsync ...

  9. spring+mybatis之声明式事务管理初识(小实例)

    前几篇的文章都只是初步学习spring和mybatis框架,所写的实例也都非常简单,所进行的数据访问控制也都很简单,没有加入事务管理.这篇文章将初步接触事务管理. 1.事务管理 理解事务管理之前,先通 ...

  10. PHPSTORM下安装XDEBUG

    本文不是教程安装XDEBUG,具体的请自行百度(我也是按照百度上的一步步来的). 以下纠正几点目前我安装时查看播客的不对之处: 1. Setting > PHP > DEBUG > ...