diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md index c08a3045..5c6f4073 100644 --- a/problems/0084.柱状图中最大的矩形.md +++ b/problems/0084.柱状图中最大的矩形.md @@ -474,7 +474,128 @@ class Solution: ### Go: -> 单调栈 +暴力解法 + +```go +func largestRectangleArea(heights []int) int { + sum := 0 + for i := 0; i < len(heights); i++ { + left, right := i, i + for left >= 0 { + if heights[left] < heights[i] { + break + } + left-- + } + for right < len(heights) { + if heights[right] < heights[i] { + break + } + right++ + } + w := right - left - 1 + h := heights[i] + sum = max(sum, w * h) + } + return sum +} + +func max(x, y int) int { + if x > y { + return x + } + return y +} +``` + +双指针解法 + +```go +func largestRectangleArea(heights []int) int { + size := len(heights) + minLeftIndex := make([]int, size) + minRightIndex := make([]int, size) + + // 记录每个柱子 左边第一个小于该柱子的下标 + minLeftIndex[0] = -1 // 注意这里初始化,防止下面while死循环 + for i := 1; i < size; i++ { + t := i - 1 + // 这里不是用if,而是不断向左寻找的过程 + for t >= 0 && heights[t] >= heights[i] { + t = minLeftIndex[t] + } + minLeftIndex[i] = t + } + // 记录每个柱子 右边第一个小于该柱子的下标 + minRightIndex[size - 1] = size; // 注意这里初始化,防止下面while死循环 + for i := size - 2; i >= 0; i-- { + t := i + 1 + // 这里不是用if,而是不断向右寻找的过程 + for t < size && heights[t] >= heights[i] { + t = minRightIndex[t] + } + minRightIndex[i] = t + } + // 求和 + result := 0 + for i := 0; i < size; i++ { + sum := heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1) + result = max(sum, result) + } + return result +} + +func max(x, y int) int { + if x > y { + return x + } + return y +} +``` + +单调栈 + +```go +func largestRectangleArea(heights []int) int { + result := 0 + heights = append([]int{0}, heights...) // 数组头部加入元素0 + heights = append(heights, 0) // 数组尾部加入元素0 + st := []int{0} + + // 第一个元素已经入栈,从下标1开始 + for i := 1; i < len(heights); i++ { + if heights[i] > heights[st[len(st)-1]] { + st = append(st, i) + } else if heights[i] == heights[st[len(st)-1]] { + st = st[:len(st)-1] + st = append(st, i) + } else { + for len(st) > 0 && heights[i] < heights[st[len(st)-1]] { + mid := st[len(st)-1] + st = st[:len(st)-1] + if len(st) > 0 { + left := st[len(st)-1] + right := i + w := right - left - 1 + h := heights[mid] + result = max(result, w * h) + } + } + st = append(st, i) + } + } + return result +} + +func max(x, y int) int { + if x > y { + return x + } + return y +} +``` + +单调栈精简 ```go func largestRectangleArea(heights []int) int {