019_接雨水
知识点:动态规划、双指针、单调栈
LeetCode第四十二题:https://leetcode-cn.com/problems/trapping-rain-water/submissions/
这题可谓经典,被各种解法秀一脸
语言:GoLang
// 单调栈
func trap(height []int) int {
length := len(height)
if length < 3 {
return 0
}
sum := 0
stack := []int{}
for i := 0; i < length; i++ {
for len(stack) > 0 && height[i] > height[stack[0]] {
top := stack[0]
stack = stack[1:]
if len(stack) == 0 {
break
}
l := stack[0]
r := i
h := min(height[l], height[r]) - height[top]
if h > 0 {
sum += (r - l - 1) * h
}
}
stack = append([]int{i}, stack...)
}
return sum
}
// 双指针版本
func trap___(height []int) int {
length := len(height)
if length < 3 {
return 0
}
sum := 0
left, right := 0, length - 1
leftMax, rightMax := height[left], height[right]
for left < right {
leftMax = max(leftMax, height[left])
rightMax = max(rightMax, height[right])
if leftMax < rightMax {
sum += leftMax - height[left]
left++
}else {
sum += rightMax - height[right]
right--
}
}
return sum
}
func max(a int, b int) int {
if a > b {
return a
}
return b
}
// dp解法:先O(n)遍历两次,分别保存每个元素的左右max值
func trap__(height []int) int {
length := len(height)
if length < 3 {
return 0
}
// 先遍历两次,计算每个元素的左右Max
leftMax, rightMax := make([]int, length), make([]int, length)
leftMax[0], rightMax[length - 1] = height[0], height[length - 1]
for j := 1; j < length; j++ {
leftMax[j] = leftMax[j - 1]
if leftMax[j] < height[j] {
leftMax[j] = height[j]
}
}
for j := length - 2; j >= 0; j-- {
rightMax[j] = rightMax[j + 1]
if rightMax[j] < height[j] {
rightMax[j] = height[j]
}
}
// 主体逻辑
sum := 0
for i := 1; i < length - 1; i++ {
area := min(leftMax[i], rightMax[i]) - height[i]
if area > 0 {
sum += area
}
}
return sum
}
// 朴素版本解法
func trap_(height []int) int {
length := len(height)
if length < 3 {
return 0
}
sum := 0
for i := 1; i < length - 1; i++ {
leftMax, rightMax := 0, 0
for j := 0; j < i; j++ {
if leftMax < height[j] {
leftMax = height[j]
}
}
for j := length - 1; j > i; j-- {
if rightMax < height[j] {
rightMax = height[j]
}
}
area := min(leftMax, rightMax) - height[i]
if area > 0 {
sum += area
}
}
return sum
}
func min(a int, b int) int {
if a > b {
return b
}
return a
}