leetcode原题链接:柱状图中最大的矩形
题目描述
给定 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
解题方法:单调栈。遍历每一个高度,取当前高度下的最大宽度,最大宽度的求法可以采用单调栈。用left[k]表示height[k]向左方向的下一个更小的元素,right[k]表示height[k]向右方向的下一个更小的元素,则此时最大宽度为right[k]-left[k]-1,注意初始化时,left数组各个初值都为-1,right数组各个初值都为n(n表示数组的大小)。
经验总结:用栈顶元素跟当前扫描的元素比较即可记住。
1. 求下一个更大的元素,用单调递减栈。
2. 求下一个更小的元素,用单调递增栈。
C++代码
#include <iostream>
#include <vector>
#include <stack>
class Solution {
public:int largestRectangleArea(std::vector<int>& heights) {int n = heights.size();std::vector<int> left(n, -1); //保存每个元素左边第一个小当前元素小的元素位置std::vector<int> right(n, n); //保存每个元素右边第一个比当前元素小的元素位置std::stack<int> st; //单调栈(求下一个更小的元素,用单调递增栈;求下一个更大的元素,用单调递减栈)// 利用单调栈计算每一个元素左边的下一个更小的元素,结果保存在left数组中// 利用单调栈计算每一个元素右边的下一个更小的元素,结果保存在right数组中for (int i = 0; i < n; i++) {while (!st.empty() && heights[st.top()] >= heights[i]) { //单调递增栈,将栈中小于当前元素的数字弹出right[st.top()] = i; //栈顶元素下一个更小的元素就是当前元素st.pop();}//栈顶元素为空或者栈顶元素if (!st.empty()) {left[i] = st.top();}st.push(i);//将当前元素的下标压入栈中}// 针对每一个高度,去找到最大的宽度计算最大面积int max_size = 0;for (int i = 0; i < n; i++) {max_size = std::max(max_size, heights[i] * (right[i] - left[i] - 1)); //注意: 这里宽度需要减1}return max_size;}
};