题目地址: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. R语言与医学统计图形-【14】ggplot2几何对象之直方密度图

    ggplot2绘图系统--几何对象之直方图.密度图 1.直方图 参数. geom_histogram(mapping = , data = , stat = 'bin', #统计变换,概率密度为den ...

  2. jenkins原理简析

    持续集成Continuous Integration(CI) 原理图: Gitlab作为git server.Gitlab的功能和Github差不多,但是是开源的,可以用来搭建私有git server ...

  3. SQL-增、删、改操作

    #查看表 select * from `竟企区域数据分析` #在表第一列新增名为"年月"的列alter table `竟企区域数据分析` add column 年月 varchar ...

  4. linux命令行快速统计文件(压缩文件)的行数

    统计(文件|压缩文件)的行数 zcat file.gz | sed -n '$='                                         #迅速.直接打印出多少行.-n 取消 ...

  5. Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

    目录 前言 1. Lua 脚本 1.1 Redis 创建并修改 Lua 环境的步骤 1.2 Lua 环境协作组件 1.3 EVAL 命令的实现 1.4 EVALSHA 命令的实现 1.5 脚本管理命令 ...

  6. day07 ORM中常用字段和参数

    day07 ORM中常用字段和参数 今日内容 常用字段 关联字段 测试环境准备 查询关键字 查看ORM内部SQL语句 神奇的双下划线查询 多表查询前提准备 常用字段 字段类型 AutoField in ...

  7. 零基础学习java------day15--------collections用法,比较器,Set(TreeSet,TreeMap),异常

    1. Collections用法 Collections: 集合的工具类public static <T> void sort(List<T> list) 排序,升序publi ...

  8. Android数据存取

    Android数据存取 一.SharedPreferencesc存取数据 SharedPreferences是使用键值对的方式来存储数据的,也就是在保存一条数据时,需要给这条数据提供一个对应的键,这样 ...

  9. 艺恩网内地总票房排名Top100信息及其豆瓣评分详情爬取

    前两天用python2写的一个小爬虫 主要实现了从http://www.cbooo.cn/Alltimedomestic这么个网页中爬取每一部电影的票房信息等,以及在豆瓣上该电影的评分信息 代码如下 ...

  10. spring注解-扩展原理

    AnnotationConfigApplicationContext(IOC容器)的有参构造方法中,在refresh()里对这些组件进行初始化 BeanPostProcessor bean后置处理器, ...