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!
解题思路:
我自己的思路就是,找到每个区间的分界点,然后再进行一次遍历就能够得到存储的水的量,例如上面的例子中,每个区间的分界点就是:1 3 7 10(下标),然后再计算每个区间内的存水量就可以了。
public class Solution {
class Node
{
public int maxnum;
public int maxindex;
public Node(int maxnum,int maxindex)
{
this.maxindex = maxindex;
this.maxnum = maxnum;
}
}
public int trap(int[] height) {
int result = 0;
List<Node> count = new ArrayList<Node>();
int logic = 0;
int maxindex = -1;
int maxnum = -1;
int length = 0;
if(height == null || height.length < 2)
return result;
for(int i = 0;i<height.length;i++)
{
if(i< height.length-1 && height[i] < height[i+1])
logic = 0;
if((i< height.length-1 && height[i] > height[i+1] && logic == 0 )||(i == height.length-1 && logic == 0))
{
logic = 1;
if(maxnum < 0)
{
maxnum = height[i];
maxindex = 0;
count.add(new Node(height[i],i));
length = 1;
}
else
{
int num1;
if(height[i] > maxnum)
{
num1 = maxindex+1;
maxindex = num1;
maxnum = height[i];
}
else
{
num1 = maxindex+1;
while(num1 < length)
{
if(height[i] > count.get(num1).maxnum)
break;
num1++;
}
}
if(num1>=count.size())
{
count.add(new Node(height[i],i));
length++;
}
else
{
count.set(num1,new Node(height[i],i));
length = num1+1;
}
}
}
}
if(length == 1)
return 0;
int x1 = count.get(0).maxindex;
int n1 = count.get(0).maxnum;
int i = 1;
while(i<length)
{
int x2 = count.get(i).maxindex;
int n2 = count.get(i).maxnum;
int minnum = Math.min(n1, n2);
for(int k = x1+1;k< x2;k++)
{
if(minnum - height[k] > 0)
result += minnum - height[k];
}
x1 = x2;
n1 = n2;
i++;
}
return result;
}
}
看起来就很繁琐,后来看了下别人的答案,发现别人的思路明显比我好很多,他的思路就是,从两边向中间遍历,先定义leftmax = 0,rightmax = 0,a = 0,b = height.length-1,每次先更新height[a]与leftmax的最大值,以及height[b]和rightmax的最大值,比较leftmax和rightmax,如果leftmax小,则说明a坐标中会存入leftmax - height[a] 的水,a++;反之,则b会存入rightmax-height[b]的水,b--。这样一次遍历就可以得到结果了。
public int trap(int[] A){
int a=0;
int b=A.length-1;
int max=0;
int leftmax=0;
int rightmax=0;
while(a<=b){
leftmax=Math.max(leftmax,A[a]);
rightmax=Math.max(rightmax,A[b]);
if(leftmax<rightmax){
max+=(leftmax-A[a]); // leftmax is smaller than rightmax, so the (leftmax-A[a]) water can be stored
a++;
}
else{
max+=(rightmax-A[b]);
b--;
}
}
return max;
}