当青训营遇上码上掘金 | 攒青豆 C++实现

39 阅读2分钟

当青训营遇上码上掘金

image.png

以上题目通常刷题的同学们肯定遇到过,直方图量面积,从前的我遇到这道题,泡了壶茶喝了一天,再次看见这个题的时候我很幸运自己刷到过

解题思路

同学们可以想象一下,怎么才能接到这个青豆呢?我们想象一个水洼,在积水前,都是下坡路,突然,发现一个上坡,水自然就被积攒起来了!

也就是说,我们可以维护一个单调栈,里面存放单调递减的数组下标,当遇到一个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刷题吧。