1. 程式人生 > 實用技巧 >leetcode刷題筆記八十四題 柱狀圖中最大的矩形

leetcode刷題筆記八十四題 柱狀圖中最大的矩形

leetcode刷題筆記八十四題 柱狀圖中最大的矩形

源地址:84. 柱狀圖中最大的矩形

問題描述:

給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。

求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。

以上是柱狀圖的示例,其中每個柱子的寬度為 1,給定的高度為 [2,1,5,6,2,3]。

圖中陰影部分為所能勾勒出的最大矩形面積,其面積為 10 個單位。

示例:

輸入: [2,1,5,6,2,3]
輸出: 10

/**
本題參考了Leetcode官方題解的方法,使用了哨兵單調棧處理方法
未使用哨兵的單調棧需要注意以下幾種情況:
1.遍歷完成後棧內仍有元素 棧頂元素非末尾元素
由棧為單調棧,末尾元素未加入棧說明末尾元素比棧頂元素高
此時先退棧,若此時棧內仍有元素, width = len - stack.pop - 1
否則 width = len
2.棧頂彈出後其高度值與新棧頂高度一致
這種情況可以採用直接彈出棧頂,不處理也可以,由於計算max值,在新棧頂計算時會進行糾正。

使用哨兵解法的好處:
由於題目中提到非負整數,將原陣列首尾兩端插入0作為哨兵。這樣就可以排除之前提到的遍歷完後棧內仍有需要計算高度值的元素,同時忽略2問題能夠大幅減少討論特例。
*/
import scala.collection.mutable.Stack
object Solution {
    def largestRectangleArea(heights: Array[Int]): Int = {
        val newHeights = Array(0).concat(heights.concat(Array(0)))
        val stack = new Stack[Int]()
        var area = 0
        stack.push(0)

        for(i <- 1 to newHeights.length-1){
            while(newHeights(stack.top) > newHeights(i)){
                val height = newHeights(stack.pop)
                val width = i - stack.top - 1
                area = Math.max(area, height*width)
            }
            stack.push(i)
        }
        return area
    }
}