leetcode笔记:Trapping Rain Water
2015-10-02 23:20
393 查看
一.题目描述
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.
![](http://img.blog.csdn.net/20151002230458034)
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!
二.题目分析
该题目需要找到规律。对某个值
再简单地说,对于当前值
那么在
总结出这个规律后一切就好办了,你可以选择第一遍从左到右遍历,计算数组的
这里的方法是先遍历一遍,找到最高的值
这些方法的时间复杂度是O(n),空间复杂度O(n)。
三.示例代码
结果:
![](http://img.blog.csdn.net/20151002230625730)
![](http://img.blog.csdn.net/20151002230634052)
四.小结
这道题的难点是发现规律,如果做到这一点,实现起来也并不是很难,但以上的方法基本需要遍历两次数组,是否能只用一次遍历就能算出结果而满足空间复杂度限制的方法呢?
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. Thanks Marcos for contributing this image!
二.题目分析
该题目需要找到规律。对某个值
height[i]来说,能trapped的最多的water取决于在
height[i]之前最高的值:
height[left_max]和在
height[i]的右边的最高值
height[right_max]。
再简单地说,对于当前值
height[i]来说,找到其左边最大值
height[left_max]和其右边最大值
height[right_max],如果:
min(height[left_max], height[right_max]) > height[i]
那么在
i这个位置上能trapped的water就是:
min(height[left_max], height[right_max]) - height[i]。
总结出这个规律后一切就好办了,你可以选择第一遍从左到右遍历,计算数组的
height[left_max];第二遍从右到左遍历,计算
height[right_max]。
这里的方法是先遍历一遍,找到最高的值
height[max_index],然后以该值的下标为分界,将数组分为两半,左右分开计算,这样,最大值
height[max_index]的左方只需计算各各值左方的最大值;同理 最大值
height[max_index]的右方只需计算各各值右方的最大值。
这些方法的时间复杂度是O(n),空间复杂度O(n)。
三.示例代码
#include <iostream> #include <vector> using namespace std; class Solution { public: int trap(vector<int>& height) { int n = height.size(); int max_index = 0; // 最高的柱子 for (int i = 0; i < n; ++i) if (height[max_index] < height[i]) max_index = i; int water = 0; // 以最高柱子为界限,左右分开扫描 for (int j = 1, left_max = 0; j < max_index; ++j) { if (height[j] < height[left_max]) water += height[left_max] - height[j]; else left_max = j; } for (int k = n - 2, right_max = n - 1; k > max_index; --k) { if (height[k] < height[right_max]) water += height[right_max] - height[k]; else right_max = k; } return water; } };
结果:
四.小结
这道题的难点是发现规律,如果做到这一点,实现起来也并不是很难,但以上的方法基本需要遍历两次数组,是否能只用一次遍历就能算出结果而满足空间复杂度限制的方法呢?
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性
- C++ Custom Control控件向父窗体发送对应的消息