42. Trapping Rain Water (Array; DP)
2015-10-09 12:02
429 查看
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!
思路:动态规划。第一次存储从开始到i最高的位置,求最高位置a之前的存水量=a与a之前最高位置b之间的水量+b与b之前最高位置c之间的水量...
第二次存储从末尾到i最高的位置,求最高位置a之后的存水量=a与a之前最高位置m之间的水量+m与m之前最高位置n之间的水量...
改进:用stack代替vector作为状态存储目前位置最高bar的下标
Result:
Input:[2,0,2]
Output:4
Expected:2
左右两次loop因为最高高度相同,所以重复计算了!
解决方法:第一次遍历考虑=的情况,第二次不考虑
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!
思路:动态规划。第一次存储从开始到i最高的位置,求最高位置a之前的存水量=a与a之前最高位置b之间的水量+b与b之前最高位置c之间的水量...
第二次存储从末尾到i最高的位置,求最高位置a之后的存水量=a与a之前最高位置m之间的水量+m与m之前最高位置n之间的水量...
class Solution { public: int trap(int A[], int n) { if(n<=2) return 0; int ret = 0; int start; int end; int* highestTillNow = new int ; //状态 highestTillNow[0] = 0; for(int i = 1; i<n;i++) //第一次扫描,从头向后 { if(A[i] > A[highestTillNow[i-1]]) { highestTillNow[i] = i; } else highestTillNow[i] = highestTillNow[i-1]; } end = highestTillNow[n-1]; //最高位置 //求最高位置前的储水量 while(end>1) { start = highestTillNow[end-1]; //最高位置前的次高位置 if(A[start]==0) break; for(int i = start+1; i <= end-1; i++) { ret += A[start]-A[i]; } end = start; } //reverse end = highestTillNow[n-1]; highestTillNow[n-1] = n-1; for(int i = n-2; i>end; i--) //第二次扫描,从尾向前 { if(A[i] > A[highestTillNow[i+1]]) { highestTillNow[i] = i; } else highestTillNow[i] = highestTillNow[i+1]; } while(end < n-2) { start = highestTillNow[end+1]; if(A[start]==0) break; for(int i = start-1; i >= end+1; i--) { ret += A[start]-A[i]; } end = start; } return ret; } };
改进:用stack代替vector作为状态存储目前位置最高bar的下标
class Solution { public: int trap(vector<int>& height) { stack<int> currentTop; int leftIndex; int rightIndex; int ret=0; if(height.empty()) return ret; //first loop from left to right to cal water at the left of the top bar currentTop.push(0); for(int i = 1; i < height.size(); i++){ if(height[i] >= height[currentTop.top()]){//Note the case = currentTop.push(i); } } rightIndex=currentTop.top(); currentTop.pop(); while(!currentTop.empty()){ leftIndex=currentTop.top(); currentTop.pop(); for(int i = leftIndex+1; i < rightIndex; i++){ ret += height[leftIndex]-height[i]; } rightIndex=leftIndex; } //then loop from right to left to cal water at the right of the top bar currentTop.push(height.size()-1); for(int i = height.size()-2; i >= 0; i--){ if(height[i] >= height[currentTop.top()]){ currentTop.push(i); } } leftIndex=currentTop.top(); currentTop.pop(); while(!currentTop.empty()){ rightIndex=currentTop.top(); currentTop.pop(); for(int i = leftIndex+1; i < rightIndex; i++){ ret += height[rightIndex]-height[i]; } leftIndex=rightIndex; } return ret; } };
Result:
Input:[2,0,2]
Output:4
Expected:2
左右两次loop因为最高高度相同,所以重复计算了!
解决方法:第一次遍历考虑=的情况,第二次不考虑
class Solution { public: int trap(vector<int>& height) { stack<int> currentTop; int leftIndex; int rightIndex; int ret=0; if(height.empty()) return ret; //first loop from left to right to cal water at the left of the top bar currentTop.push(0); for(int i = 1; i < height.size(); i++){ if(height[i] >= height[currentTop.top()]){//Note the case = currentTop.push(i); } } rightIndex=currentTop.top(); currentTop.pop(); while(!currentTop.empty()){ leftIndex=currentTop.top(); currentTop.pop(); for(int i = leftIndex+1; i < rightIndex; i++){ ret += height[leftIndex]-height[i]; } rightIndex=leftIndex; } //then loop from right to left to cal water at the right of the top bar currentTop.push(height.size()-1); for(int i = height.size()-2; i >= 0; i--){ if(height[i] > height[currentTop.top()]){ //neglect case = currentTop.push(i); } } leftIndex=currentTop.top(); currentTop.pop(); while(!currentTop.empty()){ rightIndex=currentTop.top(); currentTop.pop(); for(int i = leftIndex+1; i < rightIndex; i++){ ret += height[rightIndex]-height[i]; } leftIndex=rightIndex; } return ret; } };
相关文章推荐
- iOS 定位服务
- iOS9AdaptationTips
- android——AS中添加Jar包、so文件、Assets资源文件
- ActionBar与android—API版本的关系
- Android布局优化
- iOS UIWebView 图片大小调整
- 项目适配iOS9遇到的一些问题及解决办法(更新两个小问题)
- iOS获取设备版本信息
- Android手动清除APP中Data目录下的文件
- object类型转string类型(的三种方法)
- 告别findViewById,android IOC初探
- IOS中堆和栈的区别
- Unity人工智能学习—确定性AI算法之追踪算法五
- iOS开发MAC下配置svn
- iOS苹果官方Demo合集
- Xcode模拟器不能选择 强制打开提示iOS Simulator 意外退出
- 采用oauth2.0授权导致更换账号时使用原账号自动登录
- 广播退出多个Activity
- iOS9.0修改状态栏颜色
- Android4.3 蓝牙BLE初步