https://leetcode.com/problems/trapping-rain-water/description/
给出一个整数数组,每一个元素代表数轴上宽度为1的矩形的高度,,这些矩形紧紧相邻。想象向这些矩形中下雨,现在要求计算可以存储多少雨水。
1.暴力解法
我们分别去计算每个小矩形上面可以存储的雨水,最后将其加和。那么首先就是一个外层循环去遍历每一个矩形。下一步解决确定每个矩形上方有多少雨水的问题,对于每一个矩形,我们需要从两侧向中间逼近,分别找到这个矩形两侧最高的矩形高度,这很容易,确定好这两个值后,再分下面三种情况进行讨论:
这种方法是在找规律,然后用代码实现出来,时间复杂度 n2 n 2 ,空间复杂度1,solution里面还介绍了一种动态规划的方法,是用空间换取时间,下面介绍
2.动态规划
时间复杂度n,空间复杂度n。
整体思路与暴力解发相同,只是调用了C++里max函数找到左右两侧的最大值,并将其放入到新开辟空间的vector中。具体操作可以看下面的代码。
3.双指针法
这种方法其实也是一种找规律的方法,solution里面有一张动态图用来说明具体的思路,大家可以参考。这里只贴出相应的伪代码,很清晰,也很容易写出代码。
暴力解法
class Solution {
public int trap(int[] height) {
int left, right;
int max_left, max_right;
int water = 0;
int len = height.length;
for(int i = 1; i < len-1; i++){
left = 0;
right = len-1;
max_left = height[left];
max_right = height[right];
while(left < i){
if(height[left]>max_left){
max_left = height[left];
}
left++;
}
while(right > i){
if(height[right]>max_right){
max_right = height[right];
}
right--;
}
if(max_left>height[i] && max_right>height[i]){
water += (max_left>max_right ? max_right:max_left)-height[i];
}
}
return water;
}
}
动态规划解法
int trap(vector<int>& height)
{
if(height == null)
return 0;
int ans = 0;
int size = height.size();
vector<int> left_max(size), right_max(size);
left_max[0] = height[0];
for (int i = 1; i < size; i++) {
left_max[i] = max(height[i], left_max[i - 1]);
}
right_max[size - 1] = height[size - 1];
for (int i = size - 2; i >= 0; i--) {
right_max[i] = max(height[i], right_max[i + 1]);
}
for (int i = 1; i < size - 1; i++) {
ans += min(left_max[i], right_max[i]) - height[i];
}
return ans;
}
双指针法
class Solution {
public int trap(int[] height) {
int len = height.length;
int leftmax = 0, rightmax = 0;
int left = 0, right = len - 1;
int ans = 0;
while(left < right){
// left小
if(height[left] < height[right]){
if(height[left] > leftmax){ // 更新leftmax
leftmax = height[left];
}else{
ans += leftmax - height[left];
}
left++;
}else{ //right小
if(height[right] > rightmax){ // 更新rightmax
rightmax = height[right];
}else{
ans += rightmax - height[right];
}
right--;
}
}
return ans;
}
}