面试题 17.21. 直方图的水量
题目来源:面试题 17.21. 直方图的水量
给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的直方图,在这种情况下,可以接 6 个单位的水(蓝色部分表示水)。 感谢 Marcos 贡献此图。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1] 输出: 6
/** * @param {number[]} height * @return {number} */ var trap = function(height) { let len = height.length if(len === 0){ return 0 } let leftMax = new Array(len).fill(0), rightMax = new Array(len).fill(0); leftMax[0] = height[0] for(let i = 1;i < len;i++){ leftMax[i] = Math.max(leftMax[i-1], height[i]) } rightMax[len-1] = height[len-1] for(let i = len-2;i >=0;i--){ rightMax[i] = Math.max(rightMax[i+1], height[i]) } let res = 0 for(let i = 0;i < len;i++){ res += Math.min(leftMax[i], rightMax[i]) - height[i] } return res }; let height = [0,1,0,2,1,0,1,3,2,1,2,1] console.log(height, trap(height)) var trap = function(height) { let res = 0 let n = height.length let stack = [] for(let i = 0;i < n;i++){ while(stack.length && height[i]>height[stack[stack.length-1]]){ const top = stack.pop() if(!stack.length){ break } const left = stack[stack.length - 1] const width = i - left -1 const h = Math.min(height[i], height[left]) - height[top] res += width * h } stack.push(i) } return res }; height = [0,1,0,2,1,0,1,3,2,1,2,1] console.log(height, trap(height)) var trap = function(height) { let res = 0 let n = height.length let left = 0, right = n - 1 let leftMax = 0, rightMax = 0 while(left < right){ leftMax = Math.max(leftMax, height[left]) rightMax = Math.max(rightMax, height[right]) if(height[left] < height[right]){ res += leftMax - height[left] left += 1 }else{ res += rightMax - height[right] right -= 1 } } return res }; height = [0,1,0,2,1,0,1,3,2,1,2,1] console.log(height, trap(height))