难度:困难
题目描述:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]输出: 6
解题思路:
暴力法:循环遍历元素,每个元素的接水量相当于两边最大高度的较小值减去当前元素高度
var trap = function(height) {let total = 0;height.forEach((item, index) => {let leftMax = 0, rightMax = 0;for (var i = 0; i <= index; i++) {leftMax = Math.max(height[i], leftMax);}for (var i = index; i < height.length; i++) {rightMax = Math.max(height[i], rightMax);}total += Math.min(leftMax, rightMax) - item})return total;};
动态编程:用数组记录从左向右和从右向左的最大可能储水量。
var trap = function(height) {const size = height.length;let total = 0;let leftArr = [height[0]];let rightArr = [height[size - 1]];for (var i = 1; i < size; i++) {leftArr.push(Math.max(height[i], leftArr[i-1]));rightArr.push(Math.max(height[size-1-i], rightArr[i-1]));}for (var i = 0; i < size; i++) {total += Math.min(leftArr[i], rightArr[size-1-i]) - height[i];}return total;};
如果一侧高度高,则遍历则相对相反的反向比较。比如左侧最大高度小于右侧最大高度,若当前左指针高度小于左侧最大高度,则total加上左侧最大高度-当前左指针高度,否则将最大高度更新为当前左指针高度。
var trap = function(height) {let left = 0, right = height.length - 1, left_max = 0, right_max = 0, total = 0;while (left < right) {if (height[left] < height[right]) {height[left] < left_max ? total += left_max - height[left] : left_max = height[left];left++;} else {height[right] < right_max ? total += right_max - height[right] : right_max = height[right];right--;}}return total;};
