批里批里 (゜-゜)つ🍺 干杯~|

七つ一旋桜

园龄:4年2个月粉丝:6关注:3

当青训营遇上码上掘金

当青训营遇上码上掘金

题目

现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

样例:

输入:height = [5,0,2,1,4,0,1,0,3]

输出:17

解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

解法

暴力解法:

每个位置都向右遍历一次和向左遍历一次,通过这个求法得到这个节点可以得到的最大青豆数量。然后再从左向右遍历一次,将每个位置的青豆数量求和,这个方法的复杂度为O(n2)O(n^2)

动态规划求得到的青豆:

height数组为高度数组,先从左到右再从右到左分别两次遍历求出每个格子位置的左右主子的最高柱子高度,遍历每一列需要nn,找出左边最高和右边最高的墙加起来刚好又是一个nn, 复杂度为 O(n)O(n)

left[i] = max(left[i - 1], height[i - 1])
right[i] = max(right[i + 1], height[i + 1])

在得到高度数组leftright后,对于 0<=i<n0 <= i < n区间下标i处可得的青豆数量为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 中国大陆许可协议进行许可。

posted @   七つ一旋桜  阅读(9)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起