42.接雨水

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

示例 1:

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

示例 2:

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

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

 方法一:双指针

时间复杂度:O(n)

空间复杂度:O(1)

复制代码
 1 /**
 2  * @param {number[]} height
 3  * @return {number}
 4  */
 5 var trap = function(height) {
 6     let ans = 0;
 7     let left = 0,
 8         right = height.length - 1;
 9     let leftMax = 0,
10         rightMax = 0;
11     while (left < right) {
12         leftMax = Math.max(leftMax, height[left]);
13         rightMax = Math.max(rightMax, height[right]);
14         if (height[left] < height[right]) {
15             ans += leftMax - height[left];
16             ++left;
17         } else {
18             ans += rightMax - height[right];
19             --right;
20         }
21     }
22     return ans;
23 }
复制代码

 方法二:动态规划

时间复杂度:O(n)

空间复杂度:O(n)

复制代码
 1 /**
 2  * @param {number[]} height
 3  * @return {number}
 4  */
 5 var trap = function(height) {
 6     const n = height.length;
 7     if (n === 0) {
 8         return 0;
 9     }
10     const leftMax = new Array(n).fill(0);
11     for (let i = 1; i < n; ++i) {
12         leftMax[i] = Math.max(leftMax[i - 1], height[i]);
13     }
14     const rightMax = new Array(n).fill(0);
15     rightMax[n - 1] = height[n - 1];
16     for (let i = n - 2; i >= 0; --i) {
17         rightMax[i] = Math.max(rightMax[i + 1], height[i]);
18     }
19     let ans = 0;
20     for (let i = 0; i < n; ++i) {
21         ans += Math.min(leftMax[i], rightMax[i]) - height[i];
22     }
23     return ans;
24 }
复制代码

方法三:单调栈

时间复杂度:O(n)

空间复杂度:O(n)

复制代码
 1 /**
 2  * @param {number[]} height
 3  * @return {number}
 4  */
 5 var trap = function(height) {
 6     let ans = 0;
 7     const stack = [];
 8     const n = height.length;
 9     for (let i = 0; i < n; ++i) {
10         while (stack.length && height[i] > height[stack[stack.length - 1]]) {
11             const top = stack.pop();
12             if (!stack.length) {
13                 break;
14             }
15             const left = stack[stack.length - 1];
16             const currWidth = i - left - 1;
17             const currHeight = Math.max(height[left], height[i]) - height[top];
18             ans += currWidth * currHeight;
19         }
20         stack.push(i)
21     }
22     return ans;
23 }
复制代码

 

posted @   icyyyy  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示