题目地址:https://leetcode-cn.com/problems/string-to-integer-atoi/

题目描述

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1].

In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

Example:

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6

题目大意

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

解题方法

暴力求解

让我们求总的能接多少雨水,这个题有两种解法,一种是每个位置都去判断能接多少雨水,一种是每个区间去判断接多少雨水。

最简单的暴力解法,求每个位置的储水量:

  1. 遍历每个位置,找到这个位置左边和右边的最高柱子高度;
  2. 求两个最高柱子中取最矮的高度(短板效应,短板决定盛水量);
  3. 减去当前柱子的高度就是储水量。

这个时间复杂度是O(N^2),会超时

C++代码如下。

class Solution {
public:
int trap(vector<int>& height) {
const int N = height.size();
int res = 0;
auto begin = height.begin();
auto end = height.end();
for (int i = 0; i < N; ++i) {
int left_max = *max_element(begin, begin + i + 1);
int right_max = *max_element(begin + i, end);
res += min(left_max, right_max) - height[i];
}
return res;
}
};

保存左右最大值

在上面的暴力解法中,我们知道在每个位置都要求其左右的最大柱子的高度,因此是不是可以更快速的求出来这个值呢?

在很多题目里面,都有这种做法,为了能找出每个位置左右的最大值,可以提前计算并保存。比如,使用left_max和right_max数组,分别保存每个位置的左右两边的最大高度。计算时包含了当前位置,目的是防止出现两边的柱子比当前的位置矮,减的时候出现负值。

使用两边的高度的最小值 - 当前柱子的高度就是该位置的储水量。

C++代码如下:

class Solution {
public:
int trap(vector<int>& height) {
const int N = height.size();
int res = 0;
vector<int> left_max(N, 0);
vector<int> right_max(N, 0);
for (int i = 0; i < N; ++i) {
left_max[i] = i == 0 ? height[i] : max(left_max[i - 1], height[i]);
}
for (int i = N - 1; i >= 0; --i) {
right_max[i] = i == N - 1 ? height[i] : max(right_max[i + 1], height[i]);
}
for (int i = 0; i < N; ++i) {
res += min(left_max[i], right_max[i]) - height[i];
}
return res;
}
};

单调栈

如果你考虑的是一个区间能接多少雨水的话可以使用单调栈。

考虑单调栈的原因是我们从左向右看的时候,发现只有先下降、后上升的情况,才会存储水。

图片来源甜姨的题解

我们看到每次都要向左边找到左边最高的柱子,然后求这个区间内的面积。

我们看到其实是一层一层的向上累计的。

那么,我们使用一个单调递减栈,每次遇到一个新的位置,都把栈中的元素遍历出来,找出所有的比当前位置矮的,累积计算这部分面积。

计算面积公式:(两柱子的最小高度 - 两柱子之间的最大高度)* 距离

C++代码如下:

class Solution {
public:
int trap(vector<int>& height) {
const int N = height.size();
if (N < 3) return 0;
int res = 0;
stack<int> st;
int idx = 0;
while (idx < N) {
if (st.empty() || height[idx] <= height[st.top()]) {
st.push(idx);
idx ++;
} else {
int last = st.top(); st.pop();
if (st.empty()) continue;
int distance = idx - st.top() - 1;
res += distance * (min(height[st.top()], height[idx]) - height[last]);
}
}
return res;
}
};

欢迎关注负雪明烛的刷题博客,leetcode刷题800多,每道都讲解了详细写法!

日期

2020 年 4 月 4 日 —— 全国哀悼日

【LeetCode】42. Trapping Rain Water 接雨水 (C++)的更多相关文章

  1. [LeetCode] 42. Trapping Rain Water 收集雨水

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  2. leetcode#42 Trapping rain water的五种解法详解

    leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...

  3. [array] leetcode - 42. Trapping Rain Water - Hard

    leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...

  4. LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))

    LeetCode 42. Trapping Rain Water Python解法 解题思路: 本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程. 将每一个点的高度和索引存 ...

  5. LeetCode - 42. Trapping Rain Water

    42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...

  6. leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法

    Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...

  7. [leetcode]42. Trapping Rain Water雨水积水问题

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  8. [LeetCode] 42. Trapping Rain Water 解题思路

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  9. [LeetCode]42. Trapping Rain Water雨水填坑

    这个题难点在于无法保证右边是不是有更高的墙可以保证挡住水 双指针可以解决 /* 两边指针保证,保证另外一边肯定有能挡住水的地方. 如果从一边开始,不考虑另一边,是无法保证右边肯定有挡水的墙,如果右边只 ...

随机推荐

  1. Python——MacBook Pro中安装pip

    1.系统已有python2和python3,如何检查MacBook Pro系统是否安装的有pip? 看到terminal的提示没有,有提示pip的,下面的提示,说明pip安装了. 要查看pip3是否安 ...

  2. 完美png图片添加水印类

    完美png图片添加水印类 被添加水印图片和水印图片都可以是png,保证透明无色背景,可调节透明度 <?phpclass Imgshuiyin{ /* 缩略图相关常量定义 */ const THU ...

  3. 剖析ApplicationRunner、CommandLineRunner

    需求:SpringBoot项目启动成功后执行某方法 方案:在spring-boot中提供了两种Runner接口:ApplicationRunner和CommandLineRunner,编写自己的类实现 ...

  4. 虚拟机中安装centos系统的详细过程

    linux-centos的安装 检查电脑是否开启虚拟化,只有开启虚拟化才能安装虚拟机 新建虚拟机 鼠标点进去,选中红框所示,回车 登录: 输入默认用户名(超级管理员 root) 密码:安装时设置的密码

  5. 【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(三)-SD卡的操作流程

    其他链接 [STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(一)-初步认识SD卡 [STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(二)-了解SD总线,命令的相关介绍 ...

  6. 一份不错的Java就业指导

    想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些东西呢? 本文陈列的这些内容既可以作为个人简历中的内容,也可以作为面试的时候跟面试官聊的东西,你可以把这些 ...

  7. spring注解-组件注册

    一.@Configuration+@Bean @Configuration:配置类==配置文件 @Bean:给容器中注册一个Bean:类型为返回值的类型,默认是用方法名作为id @Bean(" ...

  8. Static data members in C++

    Predict the output of following C++ program: 1 #include <iostream> 2 using namespace std; 3 4 ...

  9. Spring Boot事务支持

    一.创建项目 二.添加依赖 <dependencies> <dependency> <groupId>org.projectlombok</groupId&g ...

  10. Mockito 入门详解

    一个测试方法主要包括三部分: setup 执行操作 验证结果 public class CalculatorTest { Calculator mCalculator; @Before // setu ...