functrapV2(height []int)int { area := 0 stack := list.New() for i := range height { for { top := stack.Front() if top == nil || height[i] < height[top.Value.(int)] { break } stack.Remove(top) bottom := top.Value.(int)
// 如果栈顶的元素相同,那么只保留最后一个就可以,因为他们存储的大小一致 for { if stack.Front() == nil || height[stack.Front().Value.(int)] != height[bottom] { break } stack.Remove(stack.Front()) }
// 将要入栈的元素大于栈顶元素 出栈并计算面积 // 取两侧柱子的最小高度 - 已经计算的高度 = 剩下的可以被填充的高度 if stack.Len() > 0 { top = stack.Front() area += (Min(height[i], height[top.Value.(int)]) - height[bottom]) * (i - top.Value.(int) - 1) } } stack.PushFront(i) }
area := 0 stack := list.New() for i := range heights { for { // 保持栈顶小于当前元素 // 如果不小于,那么移除栈顶,计算当前高度的最大面积,否则直接入栈,因为添加了末尾元素0,所以即便是连续的递增,最终也会被计算 f := stack.Front() if f == nil || heights[f.Value.(int)] < heights[i] { break }
tArea := 0 stack.Remove(f)
// 获取当前的栈顶元素,来求解以当前为高度的元素的跨度 top := f.Value.(int) if stack.Len() == 0 { tArea = heights[top] * i } else { tArea = heights[top] * (i - stack.Front().Value.(int) - 1) } if tArea > area { area = tArea } } stack.PushFront(i) } return area }
2.2.1 暴力算法
计算以每个柱子为高,他能向外扩展的最大长度组成的矩形即为该柱可以形成的最大面积
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
for i := range heights {
left = i for j = i - 1; j >= 0 ; j-- { if height[j] > heights[i] { break } left = j }
right = i for j = i + 1; j <= len(heights) ; j++ { if height[j] < heights[i] { break } right = j } area = (right - left + 1) * height[i] }