字节员工是不是个个都会接雨水。。

本文解析了LeetCode中的算法题目42:计算柱子高度图中接雨水的数量,介绍了使用动态规划的方法,通过左右最大值确定每个位置可接雨水量,展示了Java、C++、C和Python的代码实现。
摘要由CSDN通过智能技术生成

最近一网友问到:字节的是不是都会接雨水,这里说的接雨水实际上是LeetCode上的一道算法题,因为这题在LeetCode上的难度为困难,并且又是字节常考的一道题,所以该网友才会这样问。

5ad9c8905612376c4013abd2a9ee81bb.png

我们来看下其他网友的回复,甚至有的网友调侃连保洁阿姨都会,从大家的评论中我们可以看到,实际上这题不算太难。

17eb9f9d97cfbf75f3d9a8ae3a570e73.png

14ba263931c85884e35a3c60f90e1ab6.png

7197d6dc91e31ab6110734392176b79b.png

b6080fbbdd17775f4d5728d304ed1a1b.png

8da8c115ce24dd4c51ddd4faf3a83c41.png

74f01861f3b6c5bc1e84bf44cec1c10e.png

19149f44b7c0269916b1940ddae74f0d.png

2d32a471e88911ca26b9e892d4e04139.png

aaf5d5493bf7281fe844ff68c92cfa74.png

问题描述

来源:LeetCode第42题

难度:困难

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

示例1:

34ede1d4f45355daaf852add956a255d.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 * 10^4

  • 0 <= height[i] <= 10^5

问题分析

这题解法比较多,可以使用双指针,单调栈以及动态规划来解决。我们这里只介绍其中的一种,看一下动态规划的解决方式。

首先从左往右遍历数组,记录每一个位置左边(包含自己)的最大值,然后再从右往左遍历数组,记录每一个位置右边(包含自己)的最大值。

两次遍历完之后我们就知道每一个位置左边和右边的最大值了,左右两边的最大值围成的区域可以看作是一个桶,桶的高度取决于这两个值的最小值,知道桶的高度就可以计算当前位置所能容纳的水了,最后只需要计算所有位置容纳的水量即可。

JAVA:

public int trap(int[] height) {
    int length = height.length;
    int[] leftMax = new int[length];
    leftMax[0] = height[0];
    for (int i = 1; i < length; ++i)// 计算左边的最大值
        leftMax[i] = Math.max(leftMax[i - 1], height[i]);

    int[] rightMax = new int[length];
    rightMax[length - 1] = height[length - 1];
    for (int i = length - 2; i >= 0; --i)// 计算右边的最大值
        rightMax[i] = Math.max(rightMax[i + 1], height[i]);

    // 根据左右两边的最大值来确定当前柱子所能容纳的水量。
    int water = 0;
    for (int i = 0; i < length; ++i)
        water += Math.min(leftMax[i], rightMax[i]) - height[i];
    return water;
}

C++:

public:
    int trap(vector<int> &height) {
        int length = height.size();
        int leftMax[length];
        leftMax[0] = height[0];
        for (int i = 1; i < length; ++i)// 计算左边的最大值
            leftMax[i] = max(leftMax[i - 1], height[i]);

        int rightMax[length];
        rightMax[length - 1] = height[length - 1];
        for (int i = length - 2; i >= 0; --i)// 计算右边的最大值
            rightMax[i] = max(rightMax[i + 1], height[i]);

        // 根据左右两边的最大值来确定当前柱子所能容纳的水量。
        int water = 0;
        for (int i = 0; i < length; ++i)
            water += min(leftMax[i], rightMax[i]) - height[i];
        return water;
    }

C:

int trap(int *height, int heightSize) {
    int leftMax[heightSize];
    leftMax[0] = height[0];
    for (int i = 1; i < heightSize; ++i)// 计算左边的最大值
        leftMax[i] = fmax(leftMax[i - 1], height[i]);

    int rightMax[heightSize];
    rightMax[heightSize - 1] = height[heightSize - 1];
    for (int i = heightSize - 2; i >= 0; --i)// 计算右边的最大值
        rightMax[i] = fmax(rightMax[i + 1], height[i]);

    // 根据左右两边的最大值来确定当前柱子所能容纳的水量。
    int water = 0;
    for (int i = 0; i < heightSize; ++i)
        water += fmin(leftMax[i], rightMax[i]) - height[i];
    return water;
}

Python:

def trap(self, height: List[int]) -> int:
    length = len(height)
    leftMax = [0] * length
    leftMax[0] = height[0]
    for i in range(1, length):  # 计算左边的最大值
        leftMax[i] = max(leftMax[i - 1], height[i])

    rightMax = [0] * length
    rightMax[length - 1] = height[length - 1]
    for i in range(length - 2, -1, -1):  # 计算右边的最大值
        rightMax[i] = max(rightMax[i + 1], height[i])

    # 根据左右两边的最大值来确定当前柱子所能容纳的水量。
    water = 0
    for i in range(0, length):
        water += min(leftMax[i], rightMax[i]) - height[i]
    return water

0331fde386da5da6eef78eca4a73a3fc.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值