leetcode 42. 接雨水 golang实现

描述
给定n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

思路
暴力法:
求出每一列的左右列的最大值 maxLeft maxRight 在求出 min(maxLeft, maxRight) - height[i] 即为本列的雨水
动态规划:
暴力法基础上 动态规划 求maxLeft[i] = Max(maxLeft[i-1],height[i-1]) maxRight=Max(maxRight[i+1],height[i+1]
双指针:
指定left=1 right=l-1
maxLeft 代表的是0-left的最大值
maxRight 代表的是right - len-1的最大值
如果maxLeft < maxRight 说明 left 的左边最大值maxLeft 一定小于右边最大值 右边最大值不一定是maxRight 但一定小于 是不是我们不关心
如果maxLeft >= maxRight 说明 right 右边最大值 maxRight 一定小于right的左边最大值 但right左边最大值不一定是maxLeft 但一定小于 是不是我们不关心
实现
// 42 接雨水
func Trap(height []int) int {  // 暴力法 
	var ans int

	cols := len(height)

	for i := 1; i < cols-1; i++{
		var maxLeft int
		var maxRight int
		var lower int

		for j := 0; j < i; j++{
			maxLeft = Max(maxLeft, height[j])
		}

		for j := i + 1; j < cols; j++{
			maxRight = Max(maxRight, height[j])
		}

		lower = Min(maxLeft, maxRight)

		if lower > height[i]{
			ans = ans + lower - height[i]
		}
	}

	return ans
}

func Trap2(height []int) int {  // 暴力法基础上 动态规划 
	var ans int

	cols := len(height)
	maxLeft := make([]int, cols)
	maxRight := make([]int, cols)

	for i := 1; i < cols; i++{
		maxLeft[i] = Max(maxLeft[i-1], height[i-1])
	}

	for i := cols - 2; i >= 0; i--{  // 特别注意的是 maxRight[i] 依赖 maxRight[i+1] 所以i 从大到小遍历
		maxRight[i] = Max(maxRight[i+1], height[i+1])
	}

	for i := 1; i < cols-1; i++{
		var lower int

		lower = Min(maxLeft[i], maxRight[i])

		if lower > height[i]{
			ans = ans + lower - height[i]
		}
	}

	return ans
}

func Trap3(height []int) int {  // 双指针
	var ans int
	cols := len(height)

	var left  = 1
	var right = cols - 2

	var maxLeft int
	var maxRight int

	for left <= right{
		maxLeft = Max(maxLeft, height[left - 1])
		maxRight = Max(maxRight, height[right + 1])
		if maxLeft < maxRight{
			var lower = maxLeft
			if lower > height[left]{
				ans = ans + lower - height[left]
			}
			left++
		}else{
			var lower = maxRight
			if lower > height[right]{
				ans = ans + lower - height[right]
			}
			right--
		}
	}

	return ans
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值