leetcode-42. 接雨水

在这里插入图片描述
题目链接:https://leetcode.cn/problems/trapping-rain-water/
相同题<面试题 17.21. 直方图的水量>链接:https://leetcode.cn/problems/volume-of-histogram-lcci/

思路

方法1:暴力

直观想法:
遍历数组,对于数组中的每个元素,我们找出下雨后水能达到的最高位置Min(Left, Right),等于两边最大高度的较小值减去当前高度的值。

算法:

  • 初始化 ans=0
  • 从左往右扫描数组
    • 初始化 max_Left = 0和 max_Right = 0
    • 从当前元素向左扫描,找到最高点
      • max_Left = max(max_Left, height[j])
    • 从当前元素向右扫描,找到最高点
      • max_Right = max(max_Right , height[j])
    • 将 max(0, min(max_Left, max_Right) - height[i]) 累加到ans

代码示例

func trap(height []int) int {
    ans := 0
    min := func(a, b int) int{
        if a > b{
            return b
        }
        return a
    }
    max := func(a, b int) int{
        if a > b{
            return a
        }
        return b
    }
    for i := 1; i < len(height) - 1; i++{
        max_Left, max_Right := 0, 0
        for j := 0; j < i; j++{
            max_Left = max(max_Left, height[j])
        }
        for j := i + 1; j < len(height); j++{
            max_Right = max(max_Right, height[j])
        }
        ans += max(0, min(max_Left, max_Right) - height[i])
    }
    return ans
}

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n2) 每个元素都要从左往右扫描一遍数组
  • 空间复杂度:O(1)

方法2:动态编程

直观想法:
既然我们每个元素都要从左往右扫描一遍数组找两边的最大值,不如我们提前把左右两边的最大值存入数组,用空间换时间的方法。

算法

  • 找到数组从下标 i 到最左端最高的条形块高度max_Left
  • 找到数组从下标 i 到最右端最高的条形块高度max_Right
  • 遍历一次数组
    • 将 max(0, min(max_Left[i], max_Right[i]) - height[i]) 累加到ans

代码示例

func trap(height []int) int {
    lm := make([]int, len(height))
    rm := make([]int, len(height))
    min := func(a, b int) int{
        if a > b{
            return b
        }
        return a
    }
    max := func(a, b int) int{
        if a < b{
            return b
        }
        return a
    }
    for i := range height{
        if i == 0{
            lm[i] = height[i]
        }else{
            lm[i] = max(height[i], lm[i - 1])
        }
    }
    for i := len(height) - 1; i >= 0; i--{
        if i == len(height) - 1{
            rm[i] = height[i]
        }else{
            rm[i] = max(height[i], rm[i + 1])
        }
    }
    ans := 0
    for i := range height{
        ans += max(0, min(lm[i], rm[i]) - height[i])
    }
    return ans
}

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n)
    • 存储最大高度数组,需要两次遍历,每次 O(n)
    • 最后更新ans遍历数组,也是O(n)
  • 空间复杂度:O(n)
    • 和方法 1 相比使用了额外的 O(n)空间用来放置 max_Left 和 max_Right 数组。

参考链接:https://leetcode.cn/problems/trapping-rain-water/solution/jie-yu-shui-by-leetcode/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lin钟一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值