Leetcode 84. 柱状图中最大的矩形(困难)
LeetCode 最大 矩形 困难 柱状图 84
2023-09-11 14:15:38 时间
一、题目
1、题目描述
给定 n n n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例2:
输入: heights = [2,4]
输出: 4
2、基础框架
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
}
};
3、原题链接
二、解题报告
1、思路分析
例子:
那么最大的长方形面积是如下图中的红色区域:
整体思路就是 必须以每个位置的直方图作为高的长方形能扩多远,遇到相同的高度时进行错化处理,最终是能计算正确的。
如何找到以每个位置的直方图作为高的长方形能扩充的范围呢?
找到每个位置左右最近的比它矮的直方图,除了这两个位置不能到达,其他位置就是它所能扩充的范围。
2、时间复杂度
O ( n ) O(n) O(n)
3、代码详解
- C++版
//不使用系统stack的解法
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if (heights.size() == 0) return 0;
int n = heights.size();
int _stack[n]; //准备一个栈,此处使用数组替代系统栈
memset(_stack, 0, sizeof(_stack));
int si = -1;
int ans = 0;
for (int i = 0; i < n; i++) {
while (si != -1 && heights[_stack[si]] >= heights[i]) { //栈不为空 且 栈顶元素对应的值>=当前元素位置对应的值
int cur = heights[_stack[si--]]; //获取栈顶位置的直方图高度
int left = si == -1 ? -1 : _stack[si]; //找到左边最近的比栈顶位置直方图低的位置
ans = max(ans, (i - left - 1) * cur); //右边最近的比栈顶位置直方图低的是i位置
//所以以cur为高度的长方形能扩充的范围就是[left + 1, i - 1],宽度为(i - left - 1)
}
_stack[++si] = i;
}
while (si != -1) { //遍历完数组后,栈中还有数据,则单独结算
int cur = heights[_stack[si--]];
int left = si == -1 ? -1 : _stack[si];
ans = max(ans, (n - left - 1) * cur);
}
return ans;
}
};
//使用系统stack的解法
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if (heights.size() == 0) return 0;
stack<int> sta;
int area = 0;
for (int i = 0; i < heights.size(); i++) {
while (!sta.empty() && heights[sta.top()] >= heights[i]) {
int j = sta.top();
sta.pop();
int k = sta.empty() ? -1 : sta.top();
area = max(area, (i - k - 1) * heights[j]);
}
sta.push(i);
}
while (!sta.empty()) {
int j = sta.top();
sta.pop();
int k = sta.empty() ? -1 : sta.top();
int curArea = (heights.size() - k - 1) * heights[j];
area = max(area, curArea);
}
return area;
}
};
- Java 版
public class LargestRectangleInHistogram {
//使用系统栈
public static int largestRectangleArea1(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int maxArea = 0;
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] <= height[stack.peek()]) {
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int curArea = (i - k - 1) * height[j];
maxArea = Math.max(maxArea, curArea);
}
stack.push(i);
}
while (!stack.isEmpty()) {
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int curArea = (height.length - k - 1) * height[j];
maxArea = Math.max(maxArea, curArea);
}
return maxArea;
}
//使用数组替代系统栈
public static int largestRectangleArea2(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int N = height.length;
int[] stack = new int[N];
int si = -1;
int maxArea = 0;
for (int i = 0; i < height.length; i++) {
while (si != -1 && height[i] <= height[stack[si]]) {
int j = stack[si--];
int k = si == -1 ? -1 : stack[si];
int curArea = (i - k - 1) * height[j];
maxArea = Math.max(maxArea, curArea);
}
stack[++si] = i;
}
while (si != -1) {
int j = stack[si--];
int k = si == -1 ? -1 : stack[si];
int curArea = (height.length - k - 1) * height[j];
maxArea = Math.max(maxArea, curArea);
}
return maxArea;
}
}
相关文章
- Leetcode: Max Points on a line
- Leetcode: Best Time to Buy and Sell Stock II
- 【Leetcode】2103. 环和杆(简单)
- 简单易用的leetcode开发测试工具(npm)
- [LeetCode] Excel Sheet Column Title
- [LeetCode]977. 有序数组的平方
- LeetCode 1702. 修改后的最大二进制字符串
- LeetCode 421. 数组中两个数的最大异或值
- 203、【栈与队列】leetcode ——剑指 Offer II 040. 矩阵中最大的矩形 / 85. 最大矩形:暴力+单调栈(C++/Pyhont版本)
- 90、【树与二叉树】leetcode ——104. 二叉树的最大深度:层次遍历+DFS+子问题分解(C++版本)
- 【LeetCode】223. Rectangle Area
- 【LeetCode】132. Palindrome Partitioning II
- 【LeetCode-面试算法经典-Java实现】【05-Longest Palindromic Substring(最大回文字符串)】
- [LeetCode] 1301. Number of Paths with Max Score 最大得分的路径数目
- [LeetCode] 1277. Count Square Submatrices with All Ones 统计全为 1 的正方形子矩阵
- [LeetCode] 1026. Maximum Difference Between Node and Ancestor 结点与其祖先之间的最大差值
- [LeetCode] 952. Largest Component Size by Common Factor 按公因数计算最大部分大小
- [LeetCode] 949. Largest Time for Given Digits 由给定数字组成的最大时间
- [LeetCode] 933. Number of Recent Calls 最近的调用次数
- [LeetCode] 924. Minimize Malware Spread 最大程度上减少恶意软件的传播
- [LeetCode] 644. Maximum Average Subarray II 子数组的最大平均值之二
- [LeetCode] 654. Maximum Binary Tree 最大二叉树
- [LeetCode] Maximum Average Subarray I 子数组的最大平均值
- [LeetCode] Maximum Product of Three Numbers 三个数字的最大乘积
- [LeetCode] Super Washing Machines 超级洗衣机
- [LeetCode] Number Complement 补数
- [LeetCode] Maximum Product of Word Lengths 单词长度的最大积
- [LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树
- [LeetCode] 133. Clone Graph 克隆无向图
- [LeetCode] Pascal's Triangle 杨辉三角
- leetcode 83. Remove Duplicates from Sorted List 删除排序链表中的重复元素(简单)
- 并查集介绍和基于并查集解决问题——LeetCode 952 按公因数计算最大组件大小