LeetCode 84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的 矩形的最大面积。
视频讲解文章讲解https://programmercarl.com/0084.%E6%9F%B1%E7%8A%B6%E5%9B%BE%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2.html#%E5%8F%8C%E6%8C%87%E9%92%88%E8%A7%A3%E6%B3%95
// 双指针:
class Solution {
public:int largestRectangleArea(vector& heights) {int sum = 0;for (int i = 0; i < heights.size(); i++) {int left = i;int right = i;for (; left >= 0; left--) {if (heights[left] < heights[i]) break;}for (; right < heights.size(); right++) {if (heights[right] < heights[i]) break;}int w = right - left - 1;int h = heights[i];sum = max(sum, w * h);}return sum;}
};
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
// 动态规划:
class Solution {
public:int largestRectangleArea(vector& heights) {vector minLeftIndex(heights.size());vector minRightIndex(heights.size());int size = heights.size();// 记录每个柱子 左边第一个小于该柱子的下标minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环for (int i = 1; i < size; i++) {int t = i - 1;// 这里不是用if,而是不断向左寻找的过程while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];minLeftIndex[i] = t;}// 记录每个柱子 右边第一个小于该柱子的下标minRightIndex[size - 1] = size; // 注意这里初始化,防止下面while死循环for (int i = size - 2; i >= 0; i--) {int t = i + 1;// 这里不是用if,而是不断向右寻找的过程while (t < size && heights[t] >= heights[i]) t = minRightIndex[t];minRightIndex[i] = t;}// 求和int result = 0;for (int i = 0; i < size; i++) {int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);result = max(sum, result);}return result;}
};
// 单调栈:
// 版本一:从栈顶到栈底严格单调递减
class Solution {
public:int largestRectangleArea(vector& heights) {stack st;heights.insert(heights.begin(), 0); // 数组头部加入元素0heights.push_back(0); // 数组尾部加入元素0st.push(0);int result = 0;// 第一个元素已经入栈,从下标1开始for (int i = 1; i < heights.size(); i++) {// 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下标if (heights[i] > heights[st.top()]) {st.push(i);} else if (heights[i] == heights[st.top()]) {st.pop(); // 这个可以加,可以不加,效果一样,思路不同st.push(i);} else {while (heights[i] < heights[st.top()]) { // 注意是whileint mid = st.top();st.pop();int left = st.top();int right = i;int w = right - left - 1;int h = heights[mid];result = max(result, w * h);}st.push(i);}}return result;}
};// 精简版:合并情况一、二,从栈顶到栈底非严格单调递减(栈中可以有高度相同的柱子)
class Solution {
public:int largestRectangleArea(vector& heights) {stack st;heights.insert(heights.begin(), 0); // 数组头部加入元素0heights.push_back(0); // 数组尾部加入元素0st.push(0);int result = 0;for (int i = 1; i < heights.size(); i++) {while (heights[i] < heights[st.top()]) {int mid = st.top();st.pop();int w = i - st.top() - 1;int h = heights[mid];result = max(result, w * h);}st.push(i);}return result;}
};