LeetCode之HOT100--042 接雨水

这是我参与11月更文挑战的20天,活动详情查看:2021最后一次更文挑战

前言

一直都计划学习数据结构与基本算法,但是平时都看一阵停一阵。现在决心坚持下去,我准备从LeetCode的HOT100开始,每天完成1~2道习题,希望通过这种方式养成持续学习的习惯。因为我是做iOS开发的,主要是用Objective-C语言,最近也在学习Swift,所以本系列的题解都将使用swift语言完成,本文更新的是LeetCode中HOT100的第20题042 接雨水。

题目

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:

rainwatertrap.png

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 
复制代码

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9
复制代码

提示:

n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
复制代码

分析

在本题中,我们需要计算每一列中可以装水的容量,但是每一列可以装水的容量又取决有其左边和右边的墙的高度,对第 i 列,其可以装水的容量与其左右两边墙的高度的的关系如下图所示。 iShot2021-11-24 15.00.53.png 对于第 i 列,其装水容量只与左右两侧的最高墙有关,具体关系是 a r e a i = m i n ( l e f t M a x , r i g h t M a x ) h e i g h t [ i ] area_i = min(leftMax, rightMax) - height[i] 。所以我们可以用两个数组来保存对于每一列,其左侧和右侧的最高墙的高度,然后计算每一列装水容量。具体思路如下:

1. 初始化数组leftMaxList、rightMaxList用来保存每一列对应的左侧和右侧最高墙的高度
2. 从左往右遍历height数组,将当前第 i 列左侧(包括当前列)最大值保存到leftMaxList[i]
3. 从右往左遍历height数组,将当前第 i 列右侧(包括当前列)最大值保存到rightMaxList[i]
4. 从左往右遍历height数组,根据第 i 列的容量计算公式 area_i = min(leftMax, rightMax) - height[i] 计算每一列的容量,并进行求和
复制代码

题解

class Solution {
    // 动态规划
    // 时间O(n) 共访问3次 一次左边 一次右边  一次计算
    // 空间O(n) 
    func trap(_ height: [Int]) -> Int {
        // write code here
        var leftMax = 0
        // 每个位置左边的最高值 最低值为当前位置的值
        var leftMaxList: [Int] = []
        for n in height {
            leftMax = max(leftMax, n)
            leftMaxList.append(leftMax)
        }

        var rightMax = 0
        // 每个位置右边的最高值 最低值为当前位置的值
        var rightMaxList: [Int] = []
        for n in height.reversed() {
            rightMax = max(rightMax, n)
            rightMaxList.insert(rightMax, at: 0)
        }
        
        //计算总容量
        var sum = 0
        for (index, n) in height.enumerated() {
            let n1 = leftMaxList[index]
            let n2 = rightMaxList[index]
            // 当前位置的容量 = 左右最高值中的低值 (低值最为当前位置的值) - 当前位置的值
            sum += (min(n1, n2) - n)
        }

        return sum
    }
}
复制代码

おすすめ

転載: juejin.im/post/7034030859434852366