您的位置:首页 > 移动开发

42. Trapping Rain Water

2017-10-26 20:48 232 查看


对于每个柱子,找到其左右两边最高的柱子,该柱子能容纳的面积就是 min(leftMostHeight,rightMostHeight) - height。所以,

1. 从左往右扫描一遍,对于每个柱子,求取左边最大值;

2. 从右往左扫描一遍,对于每个柱子,求最大右值;

3. 再扫描一遍,把每个柱子的面积并累加。

class Solution {
public:
int trap(vector<int>& height) {
int res = 0, mx = 0, n = height.size();
vector<int> dp(n, 0);
for (int i = 0; i < n; ++i) {
dp[i] = mx;
mx = max(mx, height[i]);
}
mx = 0;
for (int i = n - 1; i >= 0; --i) {
dp[i] = min(dp[i], mx);
mx = max(mx, height[i]);
if (dp[i] > height[i]) res += dp[i] - height[i];
}
return res;
}
};
一种只需要遍历一次即可的解法,这个算法需要left和right两个指针分别指向数组的首尾位置,从两边向中间扫描,在当前两指针确定的范围内,先比较两头找出较小值,如果较小值是left指向的值,则从左向右扫描,如果较小值是right指向的值,则从右向左扫描,若遇到的值比当较小值小,则将差值存入结果,如遇到的值大,则重新确定新的窗口范围,以此类推直至left和right指针重合。
class Solution {
public:
int trap(vector<int>& height) {
int res = 0, l = 0, r = height.size() - 1;
while (l < r) {
int mn = min(height[l], height[r]);
if (mn == height[l]) {
++l;
while (l < r && height[l] < mn) {
res += mn - height[l++];
}
} else {
--r;
while (l < r && height[r] < mn) {
res += mn - height[r--];
}
}
}
return res;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: