当青训营遇上码上掘金
以上题目通常刷题的同学们肯定遇到过,直方图量面积,从前的我遇到这道题,泡了壶茶喝了一天,再次看见这个题的时候我很幸运自己刷到过
解题思路
同学们可以想象一下,怎么才能接到这个青豆呢?我们想象一个水洼,在积水前,都是下坡路,突然,发现一个上坡,水自然就被积攒起来了!
也就是说,我们可以维护一个单调栈,里面存放单调递减的数组下标,当遇到一个height[i]>栈顶时,我们就认为他是一个上坡,则可以接水,那可以接多少水呢?就得看下坡的高度和上坡的高度了。而接完一轮青豆后,原本的上坡就变成了当前的下坡,即height[i]成为了top,继续新的一轮攒青豆,直到数组结束。
从左到右遍历height数组,遍历到下标i且栈sta中至少有两个元素时,栈顶为top,第二个元素为index,这是index一定是大于top的,当遇到height[i]>top,则行程了一个低洼,开始攒青豆,宽度为i-index-1,高度区两边更小的一边min(index,height[i])-top,有宽高则可以计算出该区域的面积,得到青豆的总数。
解题代码(C++)
int CatchTheGreenBeen(vector<int>& height) {
stack<int> sta;
int area = 0;
sta.push(0);
for (int i = 1; i < height.size(); ++i)
{
if (height[i] <= height[sta.top()]) {
sta.push(i);
}
else {
while (!sta.empty() && height[i] > height[sta.top()])
{
int index = sta.top();
sta.pop();
if (!sta.empty())
area += (i - sta.top() - 1) * (min(height[i], height[sta.top()]) - height[index]);
}
sta.push(i);
}
}
return area;
}
时间复杂度O(N)
空间复杂度O(N)
解题后感
第二次解这道题就感觉自己和以前有很大的不同,坚持刷题对数学逻辑思维还是有提升的,当然也不排除我还记得答案,最近一年easy题做多了,遇到困难题就想睡大觉,还记得一句很经典的话:当你觉得不会的时候,别人还有3个solution。还是去多hard刷题吧。