给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
思路
- 暴力遍历,以 height[i] 作为高时计算相关矩形面积
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var largestRectangleArea = function (heights) { let result = 0 for (let i = 0; i < heights.length; ++i) { const curVal = heights[i] let [left, right] = [i, i] while (left > 0 && heights[left - 1] >= curVal) { --left } while (right < heights.length - 1 && heights[right + 1] >= curVal) { ++right } result = Math.max(result, (right - left + 1) * curVal) } return result }
|
性能较差,个别用例出现了超时的情况,算法需要优化。 使用 leftBound、rightBound 数组维护指定下标的左右边界,leftBound[i] + 1 为左边界,rightBound[i] - 1 为右边界
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| var largestRectangleArea = function (heights) { let result = 0 const leftBound = new Array(heights.length).fill(0) const rightBound = new Array(heights.length).fill(0) { const stack = [] for (let i = 0; i < heights.length; ++i) { while (stack.length > 0 && heights[stack[stack.length - 1]] >= heights[i]) { stack.pop() } leftBound[i] = stack.length > 0 ? stack[stack.length - 1] : -1 stack.push(i) } } { const stack = [] for (let i = heights.length - 1; i >= 0; --i) { while (stack.length > 0 && heights[stack[stack.length - 1]] >= heights[i]) { stack.pop() } rightBound[i] = stack.length > 0 ? stack[stack.length - 1] : heights.length stack.push(i) } } for (let i = 0; i < heights.length; ++i) { const curVal = heights[i] result = Math.max(result, (rightBound[i] - leftBound[i] - 1) * curVal) } return result }
|