题目:
给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。
输入: [0,1,0,2,1,0,1,3,2,1,2,1] 输出: 6
一个单位的水不会流出去,当且仅当水平往左能看到墙且水平往右能看到墙。
针对每一个水平位置,我们需要知道左边最高有多高,右边最高有多高,较低的就是当前这点的水位,比如位置5,左边最高是2(位置3)右边最高3(位置7),那么水位是2,减去底部高度0,水量是2。
需要一个数组left,left[i]表示i左边(不含i)最高是多高,一个数组right,right[i]表示i右边(不含i)最高是多高。
left[0]=0,因为0没有左边了,往右遍历,我们取最大值,每一项(left[i])是前一项(left[i-1])和前一个高度(height[i-1])的最大值。
right就是相反,最后一项是0然后往左遍历。
然后定义一个变量sum作为结果,累加每个水平位置的水量。时间复杂度空间复杂度都是O(n)
/** * @param {number[]} height * @return {number} */ var trap = function(height) { let left=new Array(height.length); let right=new Array(height.length); left[0]=0; for(let i=1;i<left.length-1;i++){ left[i]=Math.max(left[i-1],height[i-1]); } right[right.length-1]=0; for(let i=right.length-2;i>0;i--){ right[i]=Math.max(right[i+1],height[i+1]); } let sum=0; for(let i=1;i<height.length-1;i++){ let minH=Math.min(left[i],right[i]); if(minH>height[i]) sum+=minH-height[i]; } return sum; };