题目链接 : https://leetcode-cn.com/problems/largest-rectangle-in-histogram/

题目描述:

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

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

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

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

示例:

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

思路:

首先,想找到第i位置最大面积是什么?

是以i为中心,向左找第一个小于heights[i]的位置left_i;向右找第一个小于于heights[i]的位置right_i,即最大面积为heights[i] * (right_i - left_i -1),如下图所示:

所以,我们的问题就变成如何找right_ileft_i?

最简单的思路就是,就是暴力法,直接分别在i左右移动

class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
res = 0
n = len(heights)
for i in range(n):
left_i = i
right_i = i
while left_i >= 0 and heights[left_i] >= heights[i]:
left_i -= 1
while right_i < n and heights[right_i] >= heights[i]:
right_i += 1
res = max(res, (right_i - left_i - 1) * heights[i])
return res

但是,这是一个时间复杂度为\(O(n^2)\),超时

接下来想办法优化.

思路一:

当我们找i左边第一个小于heights[i]如果heights[i-1] >= heights[i]其实就是和heights[i-1]左边第一个小于heights[i-1]一样.依次类推,右边同理.

思路二:栈

利用单调栈,我写过关于它一篇文章

维护一个单调递增的栈,就可以找到left_iright_i

代码:

思路一:

class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
if not heights:
return 0
n = len(heights)
left_i = [0] * n
right_i = [0] * n
left_i[0] = -1
right_i[-1] = n
for i in range(1, n):
tmp = i - 1
while tmp >= 0 and heights[tmp] >= heights[i]:
tmp = left_i[tmp]
left_i[i] = tmp
for i in range(n - 2, -1, -1):
tmp = i + 1
while tmp < n and heights[tmp] >= heights[i]:
tmp = right_i[tmp]
right_i[i] = tmp
# print(left_i)
# print(right_i)
res = 0
for i in range(n):
res = max(res, (right_i[i] - left_i[i] - 1) * heights[i])
return res

java

class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) return 0;
int n = heights.length;
int[] left_i = new int[n];
int[] right_i = new int[n];
left_i[0] = -1;
right_i[n - 1] = n;
int res = 0;
for (int i = 1; i < n; i++) {
int tmp = i - 1;
while (tmp >= 0 && heights[tmp] >= heights[i]) tmp = left_i[tmp];
left_i[i] = tmp;
}
for (int i = n - 2; i >= 0; i--) {
int tmp = i + 1;
while (tmp < n && heights[tmp] >= heights[i]) tmp = right_i[tmp];
right_i[i] = tmp;
}
for (int i = 0; i < n; i++) res = Math.max(res, (right_i[i] - left_i[i] - 1) * heights[i]);
return res;
}
}

思路二:

class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
stack = []
heights = [0] + heights + [0]
res = 0
for i in range(len(heights)):
#print(stack)
while stack and heights[stack[-1]] > heights[i]:
tmp = stack.pop()
res = max(res, (i - stack[-1] - 1) * heights[tmp])
stack.append(i)
return res

java

class Solution {
public int largestRectangleArea(int[] heights) {
int res = 0;
Deque<Integer> stack = new ArrayDeque<>();
int[] new_heights = new int[heights.length + 2];
for (int i = 1; i < heights.length + 1; i++) new_heights[i] = heights[i - 1];
//System.out.println(Arrays.toString(new_heights));
for (int i = 0; i < new_heights.length; i++) {
//System.out.println(stack.toString());
while (!stack.isEmpty() && new_heights[stack.peek()] > new_heights[i]) {
int cur = stack.pop();
res = Math.max(res, (i - stack.peek() - 1) * new_heights[cur]);
}
stack.push(i);
}
return res;
}
}

[LeetCode] 84. 柱状图中最大的矩形的更多相关文章

  1. LeetCode 84. 柱状图中最大的矩形(Largest Rectangle in Histogram)

    84. 柱状图中最大的矩形 84. Largest Rectangle in Histogram

  2. Java实现 LeetCode 84 柱状图中最大得矩形

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

  3. LeetCode 84. 柱状图中最大的矩形(Largest Rectangle in Histogram)

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

  4. leetcode 84. 柱状图中最大的矩形 JAVA

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

  5. Leetcode84. 柱状图中最大的矩形(单调栈)

    84. 柱状图中最大的矩形 前置 单调栈 做法 连续区间组成的矩形,是看最短的那一块,求出每一块左边第一个小于其高度的位置,右边也同理,此块作为最短限制.需要两次单调栈 单调栈维护递增区间,每次不满足 ...

  6. LeetCode---84. 柱状图中最大的矩形(hard)

    题目:84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 示例: 输入: [2,1,5 ...

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

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

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

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

  9. LeetCode(84): 柱状图中最大的矩形

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

随机推荐

  1. Lambda表达式匿名类实现接口方法

    Lamb表达式匿名类实现接口方法 import java.util.ArrayList; public class HandlerDemo{ public static void main(Strin ...

  2. Vue结合后台的增删改案例

    首先列表内容还是与之前的列表内容类似,不过此处我们会采用Vue中数据请求的方式来实现数据的增删.那么我们使用的Vue第三方组件就是vue-resource,vue发起请求的方式与jQuery的ajax ...

  3. HTTP与HTTPS区别(详细)

    转:http://blog.sina.com.cn/s/blog_6eb3177a0102x66r.html 1.减少http请求(合并文件.合并图片)2.优化图片文件,减小其尺寸,特别是缩略图,一定 ...

  4. node 中process进程argv,argv0,execArgv,execPath

    1.argv const {argv,argv0,execPath v,execPath} = process; argv.forEach(item=>{ console.log(item); ...

  5. 带 like 的字符串匹配查询

    1.百分号通配符  '%'  ,匹配任意长度的字符,甚至包括零字符 例:查询所有以  'a'  字母开头的水果,sql 语句如下 select f_id,f_name from fruits wher ...

  6. 实战build-react(四)一个模块的进化过程

    主框架结构 home/index.js    //模块主文件 创建Topic模块 阶段一  基础代码 import React, { Component } from 'react'; import ...

  7. Tire树简介

    又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 典型应用:用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计. 它的优点是:利用字符串的公共 ...

  8. OI多项式 简单学习笔记

    咕咕咕 先开个坑(其实是存模板来了) 一些特别简单的前置东西qwq 复数的计算 复数相加:向量相加,复数相乘.复数相乘:模长相乘,旋转量相加(就是复平面坐标轴逆时针旋转的角度) (当然也可以直接使用c ...

  9. CQOI2010 传送带

    题目链接:戳我 分别枚举线段AB上的出发点,和线段CD上的到达点,然后时间直接计算,取min就可以了. 但是这样子显然会T飞,(相当于1e5的平方吧?)所以我们进一步考虑性质. 然后打表(或者感性理解 ...

  10. quartz的配置文件说明

    # Default Properties file for use by StdSchedulerFactory # to create a Quartz Scheduler Instance, if ...