积水问题(动态规划)

积水问题(动态规划)

有一组不同高度的台阶,有一个整数组数表示,数组中每个数是台阶的高度。当开始下雨(水足够的多),台阶之间的水坑会积多少水呢?
如图:数组为[0,1,2,1,0,1,3,2,1,2,1,0], 积水为5

在这里插入图片描述

问题分析

每一栏能存多少水取决于左边最高栏和右边最高栏里面取较小值,然后与自己栏 相减得出结果,如图

在这里插入图片描述

1、先按照左边,去找最右边最高的墙
// [0 1 2 1 0 1 3 2 1 2 1 0]
// [0 1 2 2 2 2 3 3 3 3 3 3]
	var s = []int{0, 1, 2, 1, 0, 1, 3, 2, 1, 2, 1, 0}
	var leftS []int
	for i := 0; i < len(s); i++ {
		if i == 0 {
			leftS = append(leftS, s[0])
			continue
		}
		if s[i] > leftS[len(leftS)-1] {
			leftS = append(leftS, s[i])
		} else {
			leftS = append(leftS, leftS[len(leftS)-1])
		}
	}
2、同理再按照右边,去找最左边最高的墙
//[0 1 2 1 0 1 3 2 1 2 1 0]
//[3 3 3 3 3 3 3 2 2 2 1 0]

	var s = []int{0, 1, 2, 1, 0, 1, 3, 2, 1, 2, 1, 0}
	rightS := make([]int, len(s))
	for i := len(s) - 1; i >= 0; i-- {
		if i == len(s)-1 {
			rightS[i] = s[i]
			continue
		}
		if s[i] > rightS[i+1] {
			rightS[i] = s[i]
		} else {
			rightS[i] = rightS[i+1]
		}
	}
3、然后求出每一栏的积水(左边最高和右边最高的较小值 ➖当前高度)
	var total int
	for i := 0; i < len(s); i++ {
		var a int
		if rightS[i] > leftS[i] {
			a = leftS[i] - s[i]
		} else {
			a = rightS[i] - s[i]
		}
		total += a
	}
全部代码
	var s = []int{0, 1, 2, 1, 0, 1, 3, 2, 1, 2, 1, 0}
	var leftS []int
	rightS := make([]int, len(s))
	for i := 0; i < len(s); i++ {
		if i == 0 {
			leftS = append(leftS, s[0])
			continue
		}
		if s[i] > leftS[len(leftS)-1] {
			leftS = append(leftS, s[i])
		} else {
			leftS = append(leftS, leftS[len(leftS)-1])
		}
	}
	for i := len(s) - 1; i >= 0; i-- {
		if i == len(s)-1 {
			rightS[i] = s[i]
			continue
		}
		if s[i] > rightS[i+1] {
			rightS[i] = s[i]
		} else {
			rightS[i] = rightS[i+1]
		}
	}
	var total int
	for i := 0; i < len(s); i++ {
		var a int
		if rightS[i] > leftS[i] {
			a = leftS[i] - s[i]
		} else {
			a = rightS[i] - s[i]
		}
		total += a
	}
	fmt.Println(total)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值