接雨水
题目链接:接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
方法一:动态规划
class Solution {
public:
int trap(vector<int>& height) {
int ans = 0;
int left_i = 0;
int right_i[10010];
for (int i = 0;i < height.size();i++) {
right_i[i] = 0;
}
for (int i = height.size()-2;i >= 0;i--) {
right_i[i] = max(right_i[i+1],height[i+1]);
}
for (int i = 1;i < height.size()-1;i++) {
int right_i = 0;
left_i = max(left_i,height[i-1]);
if (left_i > height[i] && right_i[i] > height[i]) {
ans += min(left_i,right_i[i]) - height[i];
}
}
return ans;
}
};方法二:双指针
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
if (n <= 2) return 0; // 少于3个柱子肯定接不了水
int left = 0; // 左指针
int right = n - 1; // 右指针
int left_max = 0; // 从左往右看到的最高柱子
int right_max = 0; // 从右往左看到的最高柱子
int ans = 0;
while (left < right) {
// 谁矮,谁决定当前这边的水位上限
if (height[left] < height[right]) {
// 左边更矮,所以水位由左边的最高柱子决定
if (height[left] >= left_max) {
// 更新左边最高柱子
left_max = height[left];
} else {
// 左边这个位置可以接的水 = 左边最高 - 当前高度
ans += left_max - height[left];
}
left++; // 处理完当前 left,往右移
} else {
// 右边更矮,水位由右边的最高柱子决定
if (height[right] >= right_max) {
// 更新右边最高柱子
right_max = height[right];
} else {
// 右边这个位置可以接的水 = 右边最高 - 当前高度
ans += right_max - height[right];
}
right--; // 处理完当前 right,往左移
}
}
return ans;
}
};