cpp
class Solution {
public:
int trap(vector<int>& height) {
int sum = 0;
int i = 0;
int n = height.size();
if (n == 0 || n == 1) return 0;
while (i < n && height[i] == 0) i ++ ;
for (int j = i + 1; j < n; j ++ ) {
while (j < n && height[i] <= height[j]) i = j ++ ;
if (j == n) return sum;
int r = j + 1;
while (r < n && height[r] < height[i]) r ++ ;
if (r == n) {
//右边都比i处小,分两种情况,一种右边一直变小,一种右边有最大值,就找最大值
//求最值,如果最值等于j处值,则i ++
r = j;
while(r < n - 1 && height[r + 1] <= height[r]) r ++ ;
if (r >= n - 1) {//说明一直递减,右边没有凹陷了
return sum;
}
else {//此时r + 1处大于r处,也就是有凹陷,就要求右边的最大值
j = r;
int h = - 2e9;
for (; r < n; r ++ ) {
if (height[r] > h) {
j = r;
h = height[r];
}
}//这样就找到最大值和最大值所在的地方了,并且所找到的最大值就是h,接下来要找i的位置
while (i < j && height[i + 1] > height[j]) i ++ ;
for (i = i + 1; i < j; i ++ ) sum += h - height[i];
}
}
else {
//右边存在比i处大
j = r;
int h = min(height[i], height[j]);
for (i = i + 1; i < j; i ++ ) sum += h - height[i];
}
}
return sum;
}
};
思路就是设置两个指针l和r,两个指针分别从左指到右,最后会遍历完整个height,
把接雨水看做求凹陷处的过程。
凹陷处才有雨水。
l就是凹陷处左边,r就是凹陷处右边
当l+1处小于l时,说明l右边在下坡,那我们只要找到上坡就有凹陷。
可以分情况讨论,
1.右边存在高于l的,一定有凹陷,可以直接找到第一个高于l的处赋值给r,然后水面的高度就是l处的高度,然后计算水的含量
2.右边都低于l处,那又只有两种情况,
2.1右边不存在上坡,则后面不存在凹陷了,可以直接返回前面得到的sum
2.2右边存在上坡,则后面一定有凹陷,因为右边都比l处低,所以右边的第一个最高处,就是水坑的r,右边的这个最高处的高度就是接下来水坑里水的高度,又因为l处此时可能并不是水坑的左边界,我们就进行比较,找到最后一个高于水坑高度的l,就是左边界,然后计算水的含量