单调栈计算最大矩形面积

单调栈计算最大矩形面积
题目:给定一个数组,数组中的元素代表木板的高度。请你求出相邻木板能剪出的最大矩形面积
我们以当前列向左右分别扩展查找,直到找到比当前小的第一个元素并且标记这个元素位置,矩形的面积为当前列高*宽度(当前列可以绘制最大宽度)

package rect

import (
	"main/stacktmp"
)

// 给定一个数组,数组中的元素代表木板的高度。请你求出相邻木板能剪出的最大矩形面积
func Rect(s []int) int {
	if len(s) == 0 {
		return 0
	}
	if len(s) == 1 {
		return s[0]
	}
	// TODO
	// 比当前右边小的index 集合
	rightSmall := rightSmall(s)
	leftSmall := leftSmall(s)
	num := len(s)
	var rightPos, leftPos, ret int
	for i := 0; i < num; i++ {
		// 当前列右边比自己小坐标位置
		if rightSmall[i] == -1 {
			rightPos = num
		} else {
			rightPos = rightSmall[i]
		}
		// 当前列左边比自己小坐标位置
		leftPos = leftSmall[i]
		// fmt.Printf("i=%d,rightPos=%d,leftPos=%d \n", i, rightPos, leftPos)
		// 当前列 坐标范围
		width := rightPos - leftPos - 1
		height := s[i]
		// 求最大值
		ret = max(ret, width*height)
	}
	return ret
}

// 从左向右找到比当前元素小的index 集合
func rightSmall(s []int) []int {
	stack := &stacktmp.StackTmp{}
	ans := make([]int, len(s))
	for i := 0; i < len(s); i++ {
		for {
			if len(stack.Stack) == 0 {
				stack.Push(i)
				break
			} else {
				// 栈顶元素
				peek := stack.Peek()
				// 找到右边比当前小的元素,并且记录下表位置
				if s[i] < s[peek] {
					ans[peek] = i
					stack.Pop()
				} else {
					// 加入当前元素
					stack.Push(i)
					break
				}
			}
		}
	}

	// 没有找到右边比当前小的元素标志为-1
	for {
		if len(stack.Stack) != 0 {
			peek := stack.Peek()
			ans[peek] = -1
			stack.Pop()
		} else {
			break
		}
	}
	return ans
}

// 从右向左找到比当前元素小的index
func leftSmall(s []int) []int {
	stack := &stacktmp.StackTmp{}
	ans := make([]int, len(s))
	for i := len(s) - 1; i >= 0; i-- {
		for {
			if len(stack.Stack) == 0 {
				stack.Push(i)
				break
			} else {
				// 栈顶元素
				peek := stack.Peek()
				// 找到右边比当前小的元素,并且记录下表位置
				if s[i] < s[peek] {
					ans[peek] = i
					stack.Pop()
				} else {
					// 加入当前元素
					stack.Push(i)
					break
				}
			}
		}
	}

	// 没有找到右边比当前小的元素标志为-1
	for {
		if len(stack.Stack) != 0 {
			peek := stack.Peek()
			ans[peek] = -1
			stack.Pop()
		} else {
			break
		}
	}
	return ans
}

func max(ret, cur int) int {
	// fmt.Println(ret)
	if ret < cur {
		return cur
	}
	return ret
}

调用

import (
	"fmt"
	rect "main/rectangulatarea"
	"main/stacktmp"
)

func main() {
	list := []int{2, 1, 5, 6, 2, 3}
	ret := rect.Rect(list)
	fmt.Println(ret)
}

结果:

m@justin MINGW64 ~/Desktop/src/test
$ go run main.go
10
上一篇:leetcode刷题笔记-232. 用栈实现队列(java实现)


下一篇:宇宙最强编辑器VS Code 1.33发布,Linux用户点赞