当青训营遇上码上掘金
当青训营遇上码上掘金
题目
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
样例:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
解法
暴力解法:
每个位置都向右遍历一次和向左遍历一次,通过这个求法得到这个节点可以得到的最大青豆数量。然后再从左向右遍历一次,将每个位置的青豆数量求和,这个方法的复杂度为
动态规划求得到的青豆:
height数组为高度数组,先从左到右再从右到左分别两次遍历求出每个格子位置的左右主子的最高柱子高度,遍历每一列需要
即
left[i] = max(left[i - 1], height[i - 1])
right[i] = max(right[i + 1], height[i + 1])
在得到高度数组left
和right
后,对于 min(left[i], right[i]) - height[i]
,根据这个状态转移方程遍历一次即可得到每个位置最高可得的青豆数
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func trap(height []int) int {
n := len(height)
left := make([]int, n)
right := make([]int, n)
for i := 1; i < n; i++ {
left[i] = max(left[i - 1], height[i - 1])
}
for i := n - 2; i >= 0; i-- {
right[i] = max(right[i + 1], height[i + 1])
}
beans := 0
for i := 0; i < n; i++ {
beans += max(0, min(left[i], right[i]) - height[i])
}
return beans
}
本文作者:七つ一旋桜
本文链接:https://www.cnblogs.com/poifa/p/17716911.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步