题目leetcode:. - 力扣(LeetCode)
之前发的接雨水是在矩形外部,而这次是在内部,这次动态规划不便了,更方便的是单调栈。为什么?思路是什么?抓住核心要害,你这个柱子容量最大也得是有个最低的柱子,我们就按以每个柱子为最低点算,看能最多能装多少水,最后选个最大的,那这就要找左右第一个比其矮的柱子了,这就是典型的单调栈问题了吧,上代码:
package main
import "container/list"
// 改用单调栈,装水最多,必然需要以其中一个作为底座,找到左边第一个比其小的,右边第一个比其小的
func largestRectangleArea(heights []int) int {
leftStack := list.New()
rightStack := list.New()
n := len(heights)
leftArr := make([]int, n)
rightArr := make([]int, n)
for i := 0; i < n; i++ {
leftArr[i] = -1
}
for i := 0; i < n; i++ {
rightArr[i] = n
}
// 右边第一个比其小的
for i := 0; i < n; i++ {
if rightStack.Len() == 0 {
rightStack.PushFront(i)
} else {
for rightStack.Len() != 0 && heights[i] < heights[rightStack.Front().Value.(int)] {
ele := rightStack.Front()
rightStack.Remove(ele)
rightArr[ele.Value.(int)] = i
}
rightStack.PushFront(i)
}
}
// 左边第一个比其小的
for i := n - 1; i >= 0; i-- {
if leftStack.Len() == 0 {
leftStack.PushFront(i)
} else {
for leftStack.Len() != 0 && heights[i] < heights[leftStack.Front().Value.(int)] {
ele := leftStack.Front()
leftStack.Remove(ele)
leftArr[ele.Value.(int)] = i
}
leftStack.PushFront(i)
}
}
max := 0
for i := 0; i < n; i++ {
leftflg := leftArr[i]
rightflg := rightArr[i]
// leftflg+1 ~ rightflg-1
if (rightflg-leftflg-1)*heights[i] > max {
max = (rightflg - leftflg - 1) * heights[i]
}
}
return max
}