42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]单调栈 - 图1
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例 2:
输入:height = [4,2,0,3,2,5]
输出:9

image.png

  1. class Solution {
  2. public int trap(int[] nums) {
  3. Stack<Integer> stack = new Stack();
  4. int ans = 0;
  5. int l = 0;
  6. while(l < nums.length) {
  7. while(!stack.empty() && nums[stack.peek()] < nums[l]){
  8. int top = stack.pop();
  9. if(stack.empty())
  10. break;
  11. int h = Math.min(nums[l],nums[stack.peek()])-nums[top];
  12. int w = l - stack.peek()-1;
  13. ans += (h*w);
  14. }
  15. stack.push(l++);
  16. }
  17. return ans;
  18. }
  19. }

双指针
image.png
image.png
注意上面的最后一段话

  1. class Solution {
  2. public int trap(int[] nums) {
  3. int len = nums.length;
  4. int left = 0;
  5. int right = len-1;
  6. int lm = 0;
  7. int rm = 0;
  8. int ans = 0;
  9. // 最后一定指向的是最高的哪个,得到的数字一定是0,所以不需要=
  10. while(left < right) {
  11. if(nums[left] < nums[right]) {
  12. lm = Math.max(lm,nums[left]);
  13. ans += (lm-nums[left++]);
  14. } else {
  15. rm = Math.max(rm,nums[right]);
  16. ans+=(rm-nums[right--]);
  17. }
  18. }
  19. return ans;
  20. }
  21. }