leetcode-42. 接雨水

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

3886c996bf9047ffa5e7494c36f2a780.png


题目链接: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
}

ec800176010445758b62c0c8d1ddc6b6.png


复杂度分析


  • 时间复杂度: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
}

4a258658780144ccbde8a21b137448b6.png



复杂度分析


  • 时间复杂度: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/

目录
相关文章
|
6月前
|
容器
leetcode-407:接雨水 II
leetcode-407:接雨水 II
74 0
|
6月前
|
图计算 索引
leetcode-42:接雨水
leetcode-42:接雨水
56 0
|
算法 测试技术 图计算
|
1月前
|
算法 图计算 C++
Leetcode第42题(接雨水)
这篇文章介绍了解决LeetCode第42题“接雨水”问题的不同算法,包括双指针法和单调栈法,并提供了C++的代码实现。
17 0
Leetcode第42题(接雨水)
|
3月前
|
存储
【面试题】接雨水
【面试题】接雨水
14 0
|
5月前
|
算法 图计算
力扣经典150题第十六题:接雨水
力扣经典150题第十六题:接雨水
28 0
|
6月前
|
容器
每日一题——接雨水(单调栈)
每日一题——接雨水(单调栈)
|
6月前
|
图计算
【每日一题Day274】LC42接雨水 | 单调栈
【每日一题Day274】LC42接雨水 | 单调栈
49 0
|
算法
【LeetCode力扣】42. 接雨水
【LeetCode力扣】42. 接雨水
78 0
|
测试技术
Leecode 42. 接雨水
Leecode 42. 接雨水
96 1