Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
chencl1986 opened this issue Sep 19, 2020 · 0 comments

Comments

@chencl1986
Copy link
Owner

原题链接: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;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant