LeetCode_单调栈_困难_84.柱状图中最大的矩形

ゝ一世哀愁。 2023-10-06 19:09 120阅读 0赞

目录

  • 1.题目
  • 2.思路
  • 3.代码实现(Java)

1.题目

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

示例 1:

在这里插入图片描述

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2:

在这里插入图片描述

输入:heights = [2,4]
输出:4

提示:
1 <= heights.length <=105
0 <= heights[i] <= 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram

2.思路

(1)暴力穷举法
使用两层 for 循环穷举出所有的矩阵,然后保存最大面积并返回即可,但是该方法的时间复杂度较高,为O(n2),所以在 LeetCode 中运行时存在超时现象,并不能通过。

(2)单调栈
思路参考该 LeetCode 用户题解。

所谓单调栈,即元素值单调递增或单调递减的栈。单调栈这种数据结构,通常应用在一维数组上,如果需要解决的问题与前后元素之间的大小关系有关的话,此时可以考虑使用单调栈。例如在本题中,前后柱子的高度会影响最大矩形面积的计算。

相关题目:
LeetCode_单调栈_困难_85.最大矩形

3.代码实现(Java)

  1. class Solution {
  2. public int largestRectangleArea(int[] heights) {
  3. int length = heights.length;
  4. int maxArea = heights[0];
  5. int minLength;
  6. //暴力穷举法
  7. for (int i = 0; i < length; i++) {
  8. minLength = heights[i];
  9. for (int j = i; j < length; j++) {
  10. //求出当前矩阵的宽
  11. int width = (j > i) ? (j - i + 1) : 1;
  12. //求出当前矩阵的长,它由最小的柱子高度决定
  13. minLength = Math.min(heights[j], minLength);
  14. //求出当前矩阵的面积
  15. int curArea = width * minLength;
  16. //保存当前得到的最大矩阵面积
  17. maxArea = Math.max(maxArea, curArea);
  18. }
  19. }
  20. //返回最大面积
  21. return maxArea;
  22. }
  23. }
  24. //思路2————单调栈
  25. class Solution {
  26. public int largestRectangleArea(int[] heights) {
  27. int length = heights.length;
  28. //定义最大的矩形面积,初始值为0
  29. int maxArea = 0;
  30. //定义单调栈,此处存储数组元素的下标,保证下标对应的值从栈底到栈顶逐渐递增
  31. Deque<Integer> stack = new ArrayDeque<>();
  32. for (int i = 0; i < length; i++) {
  33. //栈不为空,并且当前元素值小于等于数组下标为栈顶元素的值
  34. while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
  35. //将栈顶元素出栈
  36. int j = stack.pop();
  37. //求左边界
  38. int left = stack.isEmpty() ? 0 : stack.peek() + 1;
  39. //计算以 heights[j] 为高度的最大矩形面积
  40. int curArea = (i - left) * heights[j];
  41. maxArea = Math.max(maxArea, curArea);
  42. }
  43. //将当前下标加入到栈中
  44. stack.push(i);
  45. }
  46. //求整个高度单调递增的柱子所能勾勒出来的矩形的最大面积
  47. while (!stack.isEmpty()) {
  48. int j = stack.pop();
  49. int left = stack.isEmpty() ? 0 : stack.peek() + 1;
  50. //此时的右边界就是数组长度
  51. int curArea = (length - left) * heights[j];
  52. maxArea = Math.max(maxArea, curArea);
  53. }
  54. return maxArea;
  55. }
  56. }
  57. //上面的代码可以再简化一下
  58. class Solution {
  59. public int largestRectangleArea(int[] heights) {
  60. int length = heights.length;
  61. int maxArea = 0;
  62. //定义单调栈,此处存储数组元素的下标,保证下标对应的值从栈底到栈顶逐渐递增
  63. Deque<Integer> stack = new ArrayDeque<>();
  64. for (int i = 0; i <= length; i++) {
  65. while (!stack.isEmpty() && (i == length || heights[stack.peek()] >= heights[i])) {
  66. int j = stack.pop();
  67. int left = stack.isEmpty() ? 0 : stack.peek() + 1;
  68. int curArea = (i - left) * heights[j];
  69. maxArea = Math.max(maxArea, curArea);
  70. }
  71. //将当前下标加入到栈中
  72. stack.push(i);
  73. }
  74. return maxArea;
  75. }
  76. }

发表评论

表情:
评论列表 (有 0 条评论,120人围观)

还没有评论,来说两句吧...

相关阅读

    相关 leetcode 84. 矩形

    思路: 单调栈    维护一个单调上升的栈。因为保证单调上升以后,从后面开始,每一个都可以作为高。为了方便计算宽度。先压入一个-1即可。 宽度计算的原理:取当前栈顶的元素