一、题目
二、分析
这篇文章不错,建议通篇学习:
【动画模拟】一下就能读懂(单调栈)-厨子哥
在此只记录一下容易错的点,每次出栈都要计算容量!
vector<int> height = {4, 2, 0, 3, 2, 5}
在3需要入栈时,要计算它与2构成的容器的宽和高,宽好说,因为栈内存的是索引,高需要记录上一次的栈顶元素。
在此就是需要记录0,这样才知道本容器的高为min(3-0,2-0)=2
。
三、代码
class Solution {
public:
int trap(vector<int>& height) {
if(height.size() == 0) return 0;
int sum(0),top(0);
stack<int> sk;
sk.push(0);
for(int i = 1; i < height.size(); i ++){
top = sk.top();
while (!sk.empty() && height[i] > height[top])
{
sk.pop();
int temp = top;
if (sk.empty())
break;
top = sk.top();
sum += (min(height[i], height[top]) - height[temp]) * (i - top - 1);
}
sk.push(i);
}
return sum;
}
};
执行用时:12 ms, 在所有 C++ 提交中击败了35.12%的用户
内存消耗:14.1 MB, 在所有 C++ 提交中击败了31.26%的用户
再贴出一种超时的解法,如果数据量不大也可以采用。
【详细通俗的思路分析,多解法】其中的解法1。
class Solution {
public:
int trap(vector<int>& height) {
int maxHeight(0), length(height.size());
for(int i = 0; i < length; i ++){
maxHeight = max(height[i], maxHeight);
}
int sum(0);
for(int i = 1; i <= maxHeight; i ++){
bool isStart = false; //标记是否开始更新 temp
int temp_sum = 0;
for (int j = 0; j < length; j++) {
if (isStart && height[j] < i) {
temp_sum++;
}
if (height[j] >= i) {
sum = sum + temp_sum;
temp_sum = 0;
isStart = true;
}
}
}
return sum;
}
};