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!
这道题为了求能存住多少水,给定一个数组,去求存水量的话,经过分析后,怎么样的数字组合才能存住水呢?当数字出现的规律呈现凹型时,即第一个数字比后面的数字大,直到遇到比第一个数字大(或等于)存水量即第一个数字与比它小的数字的差值下面用一张图来说明:
即1,0,2数字组合能存1个单位的水(1-0),2,1,2,1,3能存(2-1)+(2-0)+(2-1)=4个单位的水,下面的搜索应该从3开始,但是后面没有比3大的数字,因此略过3,从2开始,2,1,2能存(2-1)=1,所以一共是6个单位的水。但是这样的方法有问题,比如遇到3的时候,只能遍历完后面的数字才能知道没有比它大的数字,这就导致了一些无用的计算,我看到网上有方法是先找到整个数组中的最大值,然后分别计算最大值左边和最大值右边的存水量。
这里采用的方法是从左右两边向中间进行搜索,直到两边的指针重合,搜索完成。这时候需要先初始化left和right的值,如果left<=right,说明从左往右搜索肯定能找到结束的点,那么就记录能够存的水的量,当left>right时,就从右往左搜索,最后返回res的值即可。代码如下:
int len = height.length;
if(len<3){return 0;}
int l = 0;
int r = len-1;
int res=0;
while(l<r){
int left = height[l];
int right = height[r];
if(left<=right){
while(l<r&&left>=height[++l]){
res += left-height[l];
}
}
else{
while(l<r&&right>=height[--r]){
res += right-height[r];
}
}
}
return res;
先写到这儿吧,本来想写一下找最大值然后分别找最大值左右两边的存水量的,但是电脑太卡了==高考的日子,祝各位金榜题名,如果高考的同学们报计算机专业的话,高考只意味着以后你们在哪儿写代码==