[LeetCode] Trapping Rain Water 收集雨水
2015-04-08 14:46
225 查看
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
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!
这道收集雨水的题跟之前的那道 Largest Rectangle in Histogram 直方图中最大的矩形 有些类似,但是又不太一样,我最先想到的方法有些复杂,但是也能通过OJ,想法是遍历数组,找到局部最小值,方法是如果当前值大于或等于前一个值,或者当前值大于后一个值则跳过,找到了局部最小值后,然后我们首先向左找到左边的最大值,再找右边的最大值,找右边最大值时要注意当其大于左边最大时时就停止寻找了,然后算出从左边最大值到右边最大值之间能装的水量,之后从右边最大值的位置开始继续找局部最小值,以此类推直到遍历完整个数组,代码如下:
解法一:
那么我们再来看另一种方法,这种方法是基于动态规划Dynamic Programming的,我们维护一个一维的dp数组,这个DP算法需要遍历两遍数组,第一遍遍历dp[i]中存入i位置左边的最大值,然后开始第二遍遍历数组,第二次遍历时找右边最大值,然后和左边最大值比较取其中的较小值,然后跟当前值A[i]相比,如果大于当前值,则将差值存入结果,代码如下:
解法二
最后我们来看一种只需要遍历一次即可的解法,这个算法需要left和right两个指针分别指向数组的首尾位置,从两边向中间扫描,在当前两指针确定的范围内,先比较两头找出较小值,如果较小值是left指向的值,则从左向右扫描,如果较小值是right指向的值,则从右向左扫描,若遇到的值比当较小值小,则将差值存入结果,如遇到的值大,则重新确定新的窗口范围,以此类推直至left和right指针重合,具体参见代码如下:
解法三
LeetCode All in One 题目讲解汇总(持续更新中...)
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!
这道收集雨水的题跟之前的那道 Largest Rectangle in Histogram 直方图中最大的矩形 有些类似,但是又不太一样,我最先想到的方法有些复杂,但是也能通过OJ,想法是遍历数组,找到局部最小值,方法是如果当前值大于或等于前一个值,或者当前值大于后一个值则跳过,找到了局部最小值后,然后我们首先向左找到左边的最大值,再找右边的最大值,找右边最大值时要注意当其大于左边最大时时就停止寻找了,然后算出从左边最大值到右边最大值之间能装的水量,之后从右边最大值的位置开始继续找局部最小值,以此类推直到遍历完整个数组,代码如下:
解法一:
class Solution { public: int trap(int A[], int n) { int res = 0, left = 0, right = 0, level = 0; for (int i = 1; i < n - 1; ++i) { if (A[i] >= A[i - 1] || A[i] > A[i + 1]) continue; for (left = i - 1; left > 0; --left) { if (A[left] >= A[left - 1]) break; } right = i + 1; for (int j = i + 1; j < n; ++j) { if (A[j] >= A[right]) { right = j; if (A[right] >= A[left]) break; } } level = min(A[left], A[right]); for (int j = left + 1; j < right; ++j) { if (level - A[j] > 0) res += (level - A[j]); } i = right; } return res; } };
那么我们再来看另一种方法,这种方法是基于动态规划Dynamic Programming的,我们维护一个一维的dp数组,这个DP算法需要遍历两遍数组,第一遍遍历dp[i]中存入i位置左边的最大值,然后开始第二遍遍历数组,第二次遍历时找右边最大值,然后和左边最大值比较取其中的较小值,然后跟当前值A[i]相比,如果大于当前值,则将差值存入结果,代码如下:
解法二
// DP class Solution { public: int trap(int A[], int n) { int res = 0, mx = 0; vector<int> dp(n, 0); for (int i = 0; i < n; ++i) { dp[i] = mx; mx = max(mx, A[i]); } mx = 0; for (int i = n - 1; i >= 0; --i) { dp[i] = min(dp[i], mx); mx = max(mx, A[i]); if (dp[i] - A[i] > 0) res += (dp[i] - A[i]); } return res; } };
最后我们来看一种只需要遍历一次即可的解法,这个算法需要left和right两个指针分别指向数组的首尾位置,从两边向中间扫描,在当前两指针确定的范围内,先比较两头找出较小值,如果较小值是left指向的值,则从左向右扫描,如果较小值是right指向的值,则从右向左扫描,若遇到的值比当较小值小,则将差值存入结果,如遇到的值大,则重新确定新的窗口范围,以此类推直至left和right指针重合,具体参见代码如下:
解法三
// One Pass class Solution { public: int trap(int A[], int n) { int res = 0, left = 0, right = n - 1; while (left < right) { int mn = min(A[left], A[right]); if (A[left] == mn) { ++left; while (left < right && A[left] < mn) { res += (mn - A[left]); ++left; } } else { --right; while (left < right && A[right] < mn) { res += (mn - A[right]); --right; } } } return res; } };
LeetCode All in One 题目讲解汇总(持续更新中...)
相关文章推荐
- [LeetCode] 407. Trapping Rain Water II 收集雨水 II
- [LeetCode] Trapping Rain Water II 收集雨水之二
- Leetcode 407. Trapping Rain Water II 收集雨水2 解题报告
- [LeetCode] 42. Trapping Rain Water 收集雨水
- LeetCode - Trapping Rain Water 等雨水的凹槽容量
- [LeetCode]101. Trapping Rain Water收集雨水
- LeetCode:Trapping Rain Water(装雨水问题)
- [LeetCode] Trapping Rain Water 搜集雨水
- LeetCode 42. Trapping Rain Water(收集雨水Ⅰ)
- LeetCode--Trapping Rain Water(捕获雨水)Python
- LeetCode OJ 之 Trapping Rain Water (“收集”雨水)
- [LintCode] Trapping Rain Water 收集雨水
- LeetCode Trapping Rain Water等雨水的凹槽容量
- LeetCode- 42. Trapping Rain Water (JAVA)收集雨水
- LeetCode 接雨水 Trapping Rain Water 积水问题
- Leetcode刷题记——Trapping Rain Water(捕获雨水)
- [LeetCode] Trapping Rain Water
- [Leetcode]Trapping Rain Water
- Java for LeetCode 042 Trapping Rain Water
- leetcode(42) - Trapping Rain Water