幅が の各列の高さマップを表す非負の整数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:
输入:height = [4,2,0,3,2,5] 输出:9
ヒント:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
答え
この問題はダブルポインタの中でも難しいレベルの問題です。
私の最初のアイデアは、それぞれ左側と右側から始まる 2 つのポインタを使用することでした。両側は、現在のボードの高さが、以前に遭遇した最も高いボードよりも低いかどうかを判断するために使用されます。そうであれば、2 つの間の高さの差は次のようになります。このアイデアは、水を覆うために前に高い木の板があるという前提に基づいています。
ただし、最初に遭遇した木の板が最高であるという状況があるため、この考えは機能しません
公式の考え方は、左辺と右辺の両方を一度計算し、それらの間の最小のものを取ることです。
公式案を実装する際に新しい方法を考えました、最初に一番高い板がある場所を探します、やはり左辺と右辺から計算していきますが、一番高い所に当たったところで止めますそれは数えません。わかりました
完璧な解決策
class Solution {
public:
int trap(vector<int> &height) {
int highest = 0;
for (int i = 0; i < height.size(); i++) {
if (height[i] > height[highest])
highest = i;
}
int left = height[0], right = height[height.size() - 1], drop = 0, i = 1, j = height.size() - 2;
while (i < highest) {
if (height[i] < left) {
drop += left - height[i];
} else {
left = height[i];
}
i++;
}
while (j>highest) {
if (height[j] < right) {
drop += right - height[j];
} else {
right = height[j];
}
j--;
}
return drop;
}
};