写点什么

LeetCode 题解:84. 柱状图中最大的矩形,使用栈,JavaScript,详细注释

用户头像
Lee Chen
关注
发布于: 2020 年 09 月 19 日
LeetCode题解:84. 柱状图中最大的矩形,使用栈,JavaScript,详细注释

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



解题思路:



参考了官方题解中的方法二:单调栈 + 常数优化。



  1. 将元素入栈,当遇到待入栈元素小于栈顶时,就将栈中元素依次弹出,直到栈顶比入栈元素小为止。

  2. 通过第一步的操作,就保证了栈是有小到大排序。

  3. 当入栈元素比栈顶小时,入栈元素即为右边界,栈顶为高,栈顶的下一个元素为左边界,即可计算面积。

  4. 当所有元素都完成入栈操作后,如果栈中还有元素,则需要以此将栈中元素依次弹出计算面积。

  5. 在清空栈之前,栈顶为heights的最后一个元素,且栈是有小到大排序,因此栈中元素的右边界都为heights.length



/**
* @param {number[]} heights
* @return {number}
*/
var largestRectangleArea = function (heights) {
let area = 0; // 存储最大面积
let stack = [-1]; // 用栈从低到高排列元素,保证栈内高度元素只剩1个时,能够正确计算宽度
for (let i = 0; i < heights.length; i++) {
// 当遇到比栈顶元素小的值时,表示查找到了栈顶元素对应的右边界,需要将栈顶元素弹出计算面积
while (heights[i] < heights[stack[stack.length - 1]]) {
const pop = stack.pop(); // 当前高度的index
const left = stack[stack.length - 1]; // 栈顶元素为当前高度的左边界
const width = i - left - 1; // i为右边界,宽度为左右边界之差减1
area = Math.max(area, heights[pop] * width); // 取当前的最大面积
}
// 将当前值存入栈。
// 需要注意,如果所有高度都按照while循环的规则得到处理,此时的栈还有一个值为-1,push之后还剩2个值,即-1和heights的最后一个元素。
stack.push(i);
}
// 如果栈未被清空,则表示还需要继续清空栈,当前栈顶为heights中的最后一个元素,且栈是有小到大排序。也就是说栈内所有元素的右边界都在heights.length。
while (stack.length > 1) {
const pop = stack.pop(); // 当前高度的index
const left = stack[stack.length - 1]; // 栈顶元素为当前高度的左边界
const width = heights.length - left - 1; // heights.length为右边界。
area = Math.max(area, heights[pop] * width); // 取当前的最大面积
}
return area;
};



发布于: 2020 年 09 月 19 日阅读数: 37
用户头像

Lee Chen

关注

还未添加个人签名 2018.08.29 加入

还未添加个人简介

评论

发布
暂无评论
LeetCode题解:84. 柱状图中最大的矩形,使用栈,JavaScript,详细注释