<1> 接雨水

1.题目描述

在这里插入图片描述

2. 题解

在这里插入图片描述

    func trap(_ height: [Int]) -> Int {
        var sum = 0
        if height.count < 3 {
            return 0
        }
        
        var maxLeft = [Int](repeating: 0, count: height.count)
        var maxRight = [Int](repeating: 0, count: height.count)
        
        for i in 1..<height.count-1 {
            maxLeft[i] = max(maxLeft[i - 1], height[i - 1])
        }
        for i in (0...height.count - 2).reversed() {
            maxRight[i] = max(maxRight[i + 1], height[i + 1])
        }
        
        for i in 1..<height.count - 1 {
            let h = min(maxLeft[i], maxRight[i])
            if h > height[i] {
                sum = h - height[i] + sum
            }
        }
        
        return sum
    }

3. 思路

  1. 按当前列去求
  2. 剪枝操作
    (a)当数组的个数小于3个的时候,结果为0
  3. 当前列能接的雨水个数,取决于左边柱子和右边柱子的最矮的那个柱子
    (a)所以需要求左边和右边最小的柱子
    (b)数组的第一个和最后一个,永远无法接到雨水,可以排除在外
    (c)比如求第1列(按下标为1来)的时候,那么第1列的左边最高的柱子,为第0列柱子和前面0根柱子的最大值。
    举例: height = [4,2,5,3,2,4]
    先定义:var maxLeft = [Int](repeating: 0, count: height.count)
    转换为代码:
maxLeft[1] = max(height[0], maxLeft[0]) // max(4, 0) ==> 4
maxLeft[2] = max(height[1],maxLeft[1]) // max(2, 4) ==> 4
maxLeft[3] = max(height[2],maxLeft[2]) // max(5,4) ==> 5
maxLeft[4] = max(height[2],maxLeft[2]) // max(3,4) ==> 4

同理:var maxRight = [Int](repeating: 0, count: height.count)

   maxRight[4] = max(height[5],maxLeft[5]) // max(4,0) ==> 4
   maxRight[3] = max(height[4],maxLeft[4]) // max(2,4) ==> 4
   maxRight[2] = max(height[5],maxLeft[4]) // max(3,4) ==> 4
   maxRight[1] = max(height[5],maxLeft[4]) // max(5,4) ==> 5

当求第n个的时候:

// 求第一个位置的雨水
// 左边和右边的最矮的那个柱子为
//min(maxLeft[1],maxRight[1]) == max(4, 5) = 4
// 因为 height[1] == 2,小于最小的柱子4,那么这里能接的雨水为 4-2 = 2

// 求第二个位置的雨水
// 左边和右边的最矮的那个柱子为
//min(maxLeft[2],maxRight[2]) == max(4, 4) = 4
// 因为 height[2] == 5,大于于最小的柱子4,那么这里能接的雨水为 0

// 求第三个位置的雨水
// 左边和右边的最矮的那个柱子为
//min(maxLeft[3],maxRight[3]) == max(5, 4) = 5
// 因为 height[3] == 3,小于最小的柱子4,那么这里能接的雨水为 4-3 = 1

// 求第四个位置的雨水
// 左边和右边的最矮的那个柱子为
//min(maxLeft[4],maxRight[4]) == max(4, 5) = 4
// 因为 height[1] == 2,小于最小的柱子4,那么这里能接的雨水为 4-2 = 2

// ... 以此类推,求每个位置的雨水个数
// 再求和,就是最后的答案 :2 + 1 + 2 = 5

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值