面试题 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))

 

posted @ 2021-07-27 16:44  尖子  阅读(40)  评论(0编辑  收藏  举报