【LeetCode】042 Trapping Rain Water
题目:
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.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
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.
题解:
遍历数组,找到局部最小值,方法是如果当前值大于或等于前一个值,或者当前值大于后一个值则跳过。找到了局部最小值后,然后向左找左边的最大值,再向右找右边的最大值,找右边最大值时要注意当其大于左边最大时就停止寻找。然后算出从左边最大值到右边最大值之间能装的水量,之后从右边最大值的位置开始继续找局部最小值,以此类推直到遍历完整个数组。(from here)Solution 1 中height[i] > height[i + 1]是为了避免若为>=,则数组为[5,5,1,7, 1, 1, 5,2,7,6]情况,没有=为23,有=为7;
Solution 1()
class Solution {
public:
int trap(vector<int>& height) {
int result = , n = height.size(), left = , right = ;
for(int i=; i<n-; i++) {
if(height[i] >= height[i-] || height[i] > height[i+]) continue;
for(left = i-; left>; --left) {
if(height[left]>=height[left-]) break;
}
right = i + ;
for(int j=i+; j<n; ++j) {
if(height[j]>=height[right]) {
right = j;
if(height[right]>=height[left]) break;
}
}
int h = min(height[left],height[right]);
for(int k=left+; k<right; ++k) {
if(h>height[k]) result += h - height[k];
}
i = right;
}
return result;
}
};
对于每一个值,其与另外两个值组成的容器收集的雨水最大量肯定是在其左右两边的最大值作为容器的两个壁的情况下获得的,具体在题目里就是这两个最大值的较小值与当前值的差(当这个最小值大于当前值时,否则收集不到雨水)。使用动态规划,初始化一维数组vector<int> dp(n,0)。然后遍历两遍数组,第一次遍历从左边扫描找出当前位置左边的最大值,并存放到dp中;第二次遍历从右边扫描找出当前位置右边的最大值,然后与dp中保存的左边最大值比较,存下二者之中的较小值,并且将这个值与当前值比较,如果大于当前值,则收集的雨水总量应该加上这个较小值与当前值的差值。用一个数组 left[i] 表示第 i 根柱子左边最高的柱子的高度(from here)
用一个数组 right[i] 表示第 i 根柱子右边最高的柱子的高度
1.从左到右扫描,left[i] = max(left[i - 1], A[i - 1])
2.从右到左扫描,right[i] = max(right[i + 1], A[i + 1])
3.第 i 根柱子上能储蓄的水为 min(left[i], right[i]) - A[i],因为这时 left[i] 已经没用了,可以用它来存放这个值。(from here)
复杂度:时间O(n), 空间O(n)
Solution 2 ()
class Solution {
public:
int trap(vector<int>& height) {
int result = , lmax = , rmax = , n = height.size();
vector<int> dp(n,);
for(int i=; i<n; i++) {
dp[i] = lmax;
lmax = max(lmax, height[i]);
}
for(int i=n-; i>=; i--) {
dp[i] = min(dp[i], rmax);
rmax = max(rmax, height[i]);
if(dp[i] > height[i]) {
result += dp[i] - height[i];
}
}
return result;
}
};
根据上面的雨水收集的分析,任意3个值组成的雨水收集量即是两边的较小值与中间值的差值(如果前者大于后者)。因此可以设置两个指针从两头往中间遍历,这两个指针所指的值即为容器的两个壁。低的壁(较小值)决定了收集雨水的量,因此中间值设为从较小值的后续值,并且算出收集的雨水,直到遇到一个值大于这个较小值,并且更新较小值为当前值。这样只需一趟扫描就可以解决问题。(from here)
Solution 3 ()
class Solution {
public:
int trap(vector<int>& height) {
int result = , left = , right = height.size() - ;
while (left < right) {
int h = min(height[left], height[right]);
if (h == height[left]) {
++left;
while (left < right && height[left] < h) {
result += h - height[left++];
}
} else {
--right;
while (left < right && height[right] < h) {
result += h - height[right--];
}
}
}
return result;
}
};
The idea is:
1) find the highest bar.
2) traverse the bar from left the highest bar.becasue we have the highest bar in right, so, any bar higher than its right bar(s) can contain the water.
3) traverse the bar from right the highest bar.becasue we have the highest bar in left, so, any bar higher than its left bar(s) can contain the water. (from here ChenHao)
Solution 4 ()
class Solution {
public:
int trap(vector<int>& height) {
int result = , maxhigh = , maxidx = , n = height.size();
for(int i=; i<n; i++) {
if(height[i] > maxhigh) {
maxhigh = height[i];
maxidx = i;
}
}
int prehigh = ;
for(int i=; i<maxidx; ++i) {
if(height[i] > prehigh) {
prehigh = height[i];
}
result += (prehigh - height[i]);
}
prehigh = ;
for(int i=n-; i>maxidx; --i) {
if(height[i] > prehigh) {
prehigh = height[i];
}
result += (prehigh - height[i]);
} return result;
}
};
Solution 5 ()
class Solution {
int trap(vector<int>& height) {
int l = , r = height.size()-, level = , water = ;
while (l < r) {
int lower = height[height[l] < height[r] ? l++ : r--];
level = max(level, lower);
water += level - lower;
}
return water;
}
}
【LeetCode】042 Trapping Rain Water的更多相关文章
- 【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 接雨水 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力求解 保存左右最大值 单调栈 日期 题目地址:ht ...
- 【一天一道LeetCode】#42. Trapping Rain Water
一天一道LeetCode系列 (一)题目 Given n non-negative integers representing an elevation map where the width of ...
- 【Lintcode】364.Trapping Rain Water II
题目: Given n x m non-negative integers representing an elevation map 2d where the area of each cell i ...
- 【Lintcode】363.Trapping Rain Water
题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, co ...
- LeetCode 042 Trapping Rain Water
题目要求:Trapping Rain Water Given n non-negative integers representing an elevation map where the width ...
- [Leetcode][Python]42: Trapping Rain Water
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 42: Trapping Rain Waterhttps://oj.leetc ...
- 【LeetCode题意分析&解答】42. Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- LeetCode OJ 42. Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
随机推荐
- NHibernate3剖析:Mapping篇之ConfORM实战(1):概览
ORuM思想浮出 对于ORM(Object Relational Mapping)我们太熟悉了,可是我们从还有一个角度能够想象出ORuM(Object Relational un-Mapping)的思 ...
- 关于安装oracle 11g client 出现安装先决条件检查全部失败
本文转自:https://blog.csdn.net/iloli/article/details/45244159 今天我在安装Oracle11gClient时,全部显示成N/A,Oracle无法执行 ...
- c# mvc 路由规则学习片段
1.初步接触mvc 路由 routes.MapRoute( "CM", "CM/{controller}/{act ...
- 黑名单机制来临,你的应用还好么?Android P DP2最新兼容性报告出炉
5月9日,谷歌面向全球开发者发布了 Android P Beta,即 Android P DP2. 华为终端开放实验室第一时间对TOP1000主流应用兼容性进行测试,那么在版本兼容性方面各主流应用有何 ...
- 小鬼PSer
我是小鬼PSer,主要修图和做网站的,有需要可以call QQ:1805843351 微信:1805843351
- VMware unrecoverable error解决方法
把开发环境部署在虚拟机里面,重装系统后不须要再反复部署开发环境. 可是有时候异常退出虚拟机会导致错误.之前出现打开虚拟机之后,系统分辨率错误,就是点击的位置和显示的位置不一样. 于是又一次关了虚拟机, ...
- DB2 时间操作
1. SQL语句得到当前的日期,时间和时间戳 SELECT current date FROM sysibm.sysdummy1; SELECT current time FROM s ...
- python 基础 7.1 datetime 获得时间
一 datatime 的使用 object timedeta tzinfo time data dat ...
- Altium Designer 敷铜间距设置,真实有效
在任一PCB视图时,点击设计->规则,弹出规则设置对话框,如下图 找到Clearance,如下图, 使用右键单击,选择 新规则,如下图 在新规则上单击,在右侧 where the first ...
- MySQL重置root用户密码的方法【亲测可用】
1. 报错截图 2.当确认已经忘记MySQL密码,则可以通过以下方案重置root用户密码.双击打开C:\Program Files\MySQL\MySQL Server 5.1\my.ini文件,如下 ...