【LeetCode】42. Trapping Rain Water 接雨水 (C++)
- 作者: 负雪明烛
- id: fuxuemingzhu
- 个人博客:http://fuxuemingzhu.cn/
题目地址: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 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
解题方法
暴力求解
让我们求总的能接多少雨水,这个题有两种解法,一种是每个位置都去判断能接多少雨水,一种是每个区间去判断接多少雨水。
最简单的暴力解法,求每个位置的储水量:
- 遍历每个位置,找到这个位置左边和右边的最高柱子高度;
- 求两个最高柱子中取最矮的高度(短板效应,短板决定盛水量);
- 减去当前柱子的高度就是储水量。
这个时间复杂度是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++)的更多相关文章
- [LeetCode] 42. Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- leetcode#42 Trapping rain water的五种解法详解
leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...
- [array] leetcode - 42. Trapping Rain Water - Hard
leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...
- LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))
LeetCode 42. Trapping Rain Water Python解法 解题思路: 本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程. 将每一个点的高度和索引存 ...
- LeetCode - 42. Trapping Rain Water
42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...
- leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法
Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...
- [leetcode]42. Trapping Rain Water雨水积水问题
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [LeetCode] 42. Trapping Rain Water 解题思路
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [LeetCode]42. Trapping Rain Water雨水填坑
这个题难点在于无法保证右边是不是有更高的墙可以保证挡住水 双指针可以解决 /* 两边指针保证,保证另外一边肯定有能挡住水的地方. 如果从一边开始,不考虑另一边,是无法保证右边肯定有挡水的墙,如果右边只 ...
随机推荐
- python18内存管理
- 以VuePress的v1.x为基础开发-用户手册
首先配置.vuepress中的config.js module.exports = { title:"用户手册", description: '用户手册', evergreen: ...
- 巩固java第六天
巩固内容: HTML 空元素 没有内容的 HTML 元素被称为空元素.空元素是在开始标签中关闭的. <br> 就是没有关闭标签的空元素(<br> 标签定义换行). 在 XHTM ...
- Vue函数防抖和函数节流
函数防抖(debounce) 应用场景 登录.发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防 ...
- Hbase(6)【Java Api Phoenix操作Hbase】
目录 两种方式操作Phoenix 1.Thick Driver 2.Thin Driver 3.注意事项 两种方式操作Phoenix 官网:http://phoenix.apache.org/faq. ...
- 03-Collection用例管理及批量执行
当我们对一个或多个系统中的很多用例进行维护时,首先想到的就是对用例进行分类管理,同时还希望对这批用例做回归测试 .在postman也提供了这样一个功能,就是Collection .通过这个Collec ...
- Linux学习 - 脚本安装包
脚本安装包不是独立的软件包类型,常见安装的是源码包
- oracle(查询数据库对象1)
1 --查询表信息 2 xxx_tables--包含表的基本描述信息和统计信息 3 xxx_tab_columns--包含表中列的描述信息和统计信息 4 xxx_all_tables--包含当前数据库 ...
- java的bio和nio写入及读取txt文件
一.bio的写入及读取 1.采用bio之BufferedWriter 写入文件 public static void main(String[] args) throws IOException { ...
- UE4网络模块解析(一)
一. UE4网络架构 Server-Client构架 1.一个服务器,一个或多个客户端. 客户端所有的操作如击杀等都需要传到中央服务器来运算,得到的运算结果下发到各个客户端.服务器是UE4多人游戏的重 ...