首页 > 代码库 > LeetCode42:Trapping Rain Water
LeetCode42: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. Thanks Marcos for contributing this image!
这道题非常久之前做过,如今又碰到了,非常快就解了出来。
解法一
两次遍历的解法。
先进行一次遍历,找到最高的那个元素的下标,然后进行第二次遍历,第二次遍历又分成从左到最大值的遍历和从右到最大值的遍历。
从左边開始遍历时使用一个变量来记录从左边開始的极大值,假设当前遍历的元素小于这个极大值。它们之前的差值是当前点能够容纳的水量,假设当前元素大于这个极大值,那么更新极大值。
右边的遍历方式类似。例如以下图:
runtime:8ms
class Solution { public: int trap(vector<int>& height) { int maxPos=0; int maxHeight=0; int length=height.size(); for(int i=0;i<length;i++) { if(height[i]>maxHeight) { maxHeight=height[i]; maxPos=i; } } int result=0; int leftHeight=0; for(int i=0;i<maxPos;i++) { if(height[i]>leftHeight) { leftHeight=height[i]; } else { result+=leftHeight-height[i]; } } int rightHeight=0; for(int i=length-1;i>maxPos;i--) { if(height[i]>rightHeight) { rightHeight=height[i]; } else { result+=rightHeight-height[i]; } } return result; } };
解法二
另外一种解法是使用一次遍历的解法。
上面的解法之所以要遍历两次。是为了寻找最大值,这样可以保证极大值与当前值的差值是能容纳的水量,可是事实上可以不用求出最大值而是使用左边和右边当前值的最大值。假设左边的当前值较大,那么遍历右边。假设右边的当前值较大。遍历左边,这样就能保证极大值与当前值的差值是能容纳的水量。
runtime:8ms
int trap(vector<int>& height) { int length=height.size(); int result=0; int leftPos=0; int rightPos=length-1; int leftMax=0; int rightMax=0; while(leftPos<rightPos) { if(height[leftPos]<height[rightPos]) { if(height[leftPos]<leftMax) result+=leftMax-height[leftPos]; else leftMax=height[leftPos]; leftPos++; } else { if(height[rightPos]<rightMax) result+=rightMax-height[rightPos]; else rightMax=height[rightPos]; rightPos--; } } return result; }
LeetCode42:Trapping Rain Water