42. Trapping Rain Water
问题:
给定x坐标,上每一个点代表陆地的高度。
求从0~最大坐标之间,累积雨水,最多能储蓄多少水量。
Example 1: Input: height = [0,1,0,2,1,0,1,3,2,1,2,1] Output: 6 Explanation: The above elevation map (black section) 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. Example 2: Input: height = [4,2,0,3,2,5] Output: 9 Constraints: n == height.length 0 <= n <= 3 * 10^4 0 <= height[i] <= 10^5
example 1:
解法:two pointer (双指针)
思路:
❓ point: 对于每个坐标 i,所能存储的水量是多少?
= min( i 左边最高高度, i 右边最高高度 ) - height[i]
上述表达式中,要求结果,只与 i 左右两边最高高度的 最小的一方有关。
那么,假设已知 i 左边👈 最高高度 lmax,和任意一个 i 右边的高度 height[rp]
且height[rp]还 > lmax。
那么我们可确定当前 i 的储水结果=lmax-height[i]
因为,i 右边的最高高度一定是高于等于这个任意高度 height[rp]的。
右边同样可知。
那么,我们可以同时从左右两边开始向中间遍历,
lp=0, rp=size-1 开始,一直到-> lp>=rp
同时取lp以左⬅️ ,rp以右➡️ ,各自的最大值。
取更小的一方,进行结果累计。
代码参考:
1 class Solution { 2 public: 3 int trap(vector<int>& height) { 4 int res=0; 5 int lp=0, rp=height.size()-1; 6 if(lp>=rp) return res; 7 int lmax=height[lp], rmax=height[rp]; 8 while(lp<rp) { 9 //choose min side 10 if(lmax<rmax) { 11 // left 12 res += (lmax-height[lp]); 13 lp++; 14 lmax = max(lmax, height[lp]); 15 } else { 16 //right 17 res += (rmax-height[rp]); 18 rp--; 19 rmax = max(rmax, height[rp]); 20 } 21 } 22 return res; 23 } 24 };