42.雨をつかむ(難しい)
幅 の各柱の高さマップを表す非負の整数n
が与えられた場合、このように配置された柱が雨が降った後にどれだけの雨水を受け取ることができるかを計算します。1
例 1:
入力:高さ = [0,1,0,2,1,0,1,3,2,1,2,1] 出力: 6 説明:上記は配列 [0,1,0,2, 1,0 ,1,3,2,1,2,1] は高さマップを表し、この場合、6 単位の雨水を受け取ることができます (青い部分は雨水を表します)。
例 2:
入力:高さ = [4,2,0,3,2,5] 出力: 9
動的計画法
/**
* @param {number[]} height
* @return {number}
*/
var trap = function(height) {
let n = height.length;
if (n == 0) {
return 0;
}
let leftMax = new Array(n).fill(0);
leftMax[0] = height[0];
for (let i = 1; i < n; ++i) {
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
}
let rightMax = new Array(n).fill(0);
rightMax[n - 1] = height[n - 1];
for (let i = n - 2; i >= 0; --i) {
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
}
let res = 0;
for (let i = 0; i < n; ++i) {
res += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return res;
};
ダブルポインタ
/**
* @param {number[]} height
* @return {number}
*/
var trap = function(height) {
let res = 0;
let left = 0, right = height.length - 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;
} else {
res += rightMax - height[right];
--right;
}
}
return res;
};