思路:对柱子i,需要确定左边柱子最大值(mx_l)、右边柱子的最大值(mx_r);水得高度取决于两个最大值的最小值(mi),比较mi和arr[i],如果mi>arr[i],那个柱子i上的雨水就是mi-arr[i],否则就接不到雨水。
所以只需要创建数组arr_mx_l记录左边最大值、arr_mx_r记录右边最大值,然后就好算了; 这个方法的时间复杂度是O(n),空间复杂度也是O(n);
代码比较简单,相信你写起来还是比较简单的✌️😩😉
介绍下双指针法,l指向首部,r指向尾部,
重点:对比arr[l]、arr[r]二者大小,如果arr[l]<arr[r],舍弃arr[l]
让l++,这样确定了一个性质,那就是max(arr[l+1,l+2.......r])比arr[l]大,这时,只要记录左边最大值,这样对于arr[i]左右最大值都确定了,雨水就非常好求了,就是mx_l-arr[l],mx_l就是max(arr[0,1,2,...,l]);
当然arr[l]>=arr[r]也是同样的步骤,请看代码
class Solution {
public:
/**
* max water
* @param arr int整型vector the array
* @return long长整型
*/
long long maxWater(vector<int>& arr) {
// write code here
int n=arr.size();
if(n<3) return 0;
int l=0,r=n-1;
int mx_l=0,mx_r=0;//记录左边最大值、右边最大值
long long sum=0;//返回的结果,记得是long long类型的
while(l<r) {
if(arr[l]<arr[r]) {
//不要忘了更新mx_l、l
if(arr[l]<mx_l) sum+=mx_l-arr[l];
else mx_l=arr[l];
++l;
} else {
//不要忘了更新mx_r、r
if(arr[r]<mx_r) sum+=mx_r-arr[r];
else mx_r = arr[r];
--r;
}
}
return sum;
}
};