[LeetCode] 84. Largest Rectangle in Histogram(直方圖裡的最大矩形)
阿新 • • 發佈:2020-12-23
- Difficulty: Hard
- Related Topics: Array, Stack
- Link: https://leetcode.com/problems/largest-rectangle-in-histogram/
Description
Givennnon-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
給定 n 各非負整數,表示直方圖中每個柱子的高度(所有柱子的寬度都是 1),找到該立方圖中面積最大的矩形的面積。
Above is a histogram where width of each bar is 1, given height =[2,1,5,6,2,3]
.
上圖中,每個柱子的高度是 1,高度為 [2, 1, 5, 6, 2, 3]
。
The largest rectangle is shown in the shaded area, which has area =10
unit.
上圖中面積最大的矩形為陰影所示,面積為 10 個單位。
Example
Input: [2,1,5,6,2,3]
Output: 10
Solution
對於每一個 heights[i]
,其最大的矩形面積為以 heights[i]
heights[i]
的矩形範圍內不能有比 height[i]
還矮的柱子。於是我們就需要知道每個柱子左右兩邊第一個比該柱子矮的柱子。常規方法需要 \(O(N^2)\) 時間找到所有柱子的左右兩邊第一個比該柱子矮的柱子。但實際上可以利用已經計算的結果。以找 heights[i]
左邊第一個比它矮的柱子為例,如果 heights[i - 1]
比 heights[i]
更高,那麼第一個比 heights[i]
矮的柱子肯定也是比 heights[i - 1]
矮的柱子。找右邊的柱子同理。程式碼如下:
import kotlin.math.max class Solution { fun largestRectangleArea(heights: IntArray): Int { if (heights.isEmpty()) { return 0 } val lessFromLeft = IntArray(heights.size) val lessFromRight = IntArray(heights.size) lessFromLeft[0] = -1 lessFromRight[lessFromRight.lastIndex] = heights.size for (i in 1..heights.lastIndex) { var p = i - 1 while (p >= 0 && heights[p] >= heights[i]) { p = lessFromLeft[p] } lessFromLeft[i] = p } for (i in (heights.lastIndex - 1) downTo 0) { var p = i + 1 while (p < heights.size && heights[p] >= heights[i]) { p = lessFromRight[p] } lessFromRight[i] = p } var result = 0 for (i in heights.indices) { result = max(result, heights[i] * (lessFromRight[i] - lessFromLeft[i] - 1)) } return result } }