From 91d01d610c4c8e75b8d2789240f43a52bf8fe378 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 00:28:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E42.=20=E6=8E=A5=E9=9B=A8?= =?UTF-8?q?=E6=B0=B4=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0042.接雨水.md | 99 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/problems/0042.接雨水.md b/problems/0042.接雨水.md index 16c788eb..5326dd7f 100644 --- a/problems/0042.接雨水.md +++ b/problems/0042.接雨水.md @@ -534,6 +534,105 @@ class Solution: Go: JavaScript: +```javascript +//双指针 +var trap = function(height) { + const len = height.length; + let sum = 0; + for(let i = 0; i < len; i++){ + // 第一个柱子和最后一个柱子不接雨水 + if(i == 0 || i == len - 1) continue; + let rHeight = height[i]; // 记录右边柱子的最高高度 + let lHeight = height[i]; // 记录左边柱子的最高高度 + for(let r = i + 1; r < len; r++){ + if(height[r] > rHeight) rHeight = height[r]; + } + for(let l = i - 1; l >= 0; l--){ + if(height[l] > lHeight) lHeight = height[l]; + } + let h = Math.min(lHeight, rHeight) - height[i]; + if(h > 0) sum += h; + } + return sum; +}; + +//动态规划 +var trap = function(height) { + const len = height.length; + if(len <= 2) return 0; + const maxLeft = new Array(len).fill(0); + const maxRight = new Array(len).fill(0); + // 记录每个柱子左边柱子最大高度 + maxLeft[0] = height[0]; + for(let i = 1; i < len; i++){ + maxLeft[i] = Math.max(height[i], maxLeft[i - 1]); + } + // 记录每个柱子右边柱子最大高度 + maxRight[len - 1] = height[len - 1]; + for(let i = len - 2; i >= 0; i--){ + maxRight[i] = Math.max(height[i], maxRight[i + 1]); + } + // 求和 + let sum = 0; + for(let i = 0; i < len; i++){ + let count = Math.min(maxLeft[i], maxRight[i]) - height[i]; + if(count > 0) sum += count; + } + return sum; +}; + +//单调栈 js数组作为栈 +var trap = function(height) { + const len = height.length; + if(len <= 2) return 0; // 可以不加 + const st = [];// 存着下标,计算的时候用下标对应的柱子高度 + st.push(0); + let sum = 0; + for(let i = 1; i < len; i++){ + if(height[i] < height[st[st.length - 1]]){ // 情况一 + st.push(i); + } + if (height[i] == height[st[st.length - 1]]) { // 情况二 + st.pop(); // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。 + st.push(i); + } else { // 情况三 + while (st.length !== 0 && height[i] > height[st[st.length - 1]]) { // 注意这里是while + let mid = st[st.length - 1]; + st.pop(); + if (st.length !== 0) { + let h = Math.min(height[st[st.length - 1]], height[i]) - height[mid]; + let w = i - st[st.length - 1] - 1; // 注意减一,只求中间宽度 + sum += h * w; + } + } + st.push(i); + } + } + return sum; +}; + +//单调栈 简洁版本 只处理情况三 +var trap = function(height) { + const len = height.length; + if(len <= 2) return 0; // 可以不加 + const st = [];// 存着下标,计算的时候用下标对应的柱子高度 + st.push(0); + let sum = 0; + for(let i = 1; i < len; i++){ // 只处理的情况三,其实是把情况一和情况二融合了 + while (st.length !== 0 && height[i] > height[st[st.length - 1]]) { // 注意这里是while + let mid = st[st.length - 1]; + st.pop(); + if (st.length !== 0) { + let h = Math.min(height[st[st.length - 1]], height[i]) - height[mid]; + let w = i - st[st.length - 1] - 1; // 注意减一,只求中间宽度 + sum += h * w; + } + } + st.push(i); + } + return sum; +}; +``` C: