考察知识点:单调栈
题目分析:
为一个连续的牛舍盖棚时,牛舍的宽度是牛舍的个数,而牛舍的长度是其中的最小牛舍长。例如有三个牛舍,分别长 9 8 7 9 ,那么给这几个牛舍盖棚时,牛舍的宽度就是4,长度就是7。
连续牛舍中的最小长度影响了整个牛棚的长度。为了能得到更大的牛棚面积,我们发现,如果连续牛舍中有一个牛舍长度较小,那么最好是宽度能取宽一点,就是牛舍的个数多一点。先假设牛舍中最小的长度不变,我们扩大牛舍的范围,发现对结果是增益的,因为长不变,宽在增大;扩大的极限在哪里呢,就是取完所有牛舍,或者左边或右边再扩大一个牛舍时,最小长度会变小。
如果取这个更短的牛舍,结果可能得不偿失。但是我们也看看它的极限,也许是更好的解决方案呢?
因此,我们不断假设每一个牛舍都是连续牛舍中最短的牛舍,找到左右边界(即离该牛舍最近的更短的牛舍,或者是取完左边或右边所有牛舍),计算此时的面积。遍历所有牛舍时维护一个最小值即可。
我们发现,取离某个牛舍最近的更短的牛舍可以用单调栈来解决。
所用编程语言:C++
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param areas int整型vector * @return int整型 */ int maxArea(vector<int>& areas) { // write code here int size = areas.size(); stack<int> stk; vector<int> left(size), right(size); int res = 0; //找到左边第一个比当前值小的牛舍长度 for (int i = 0; i < size; i++) { while (!stk.empty() && areas[stk.top()] >= areas[i]) stk.pop(); left[i] = stk.empty() ? -1 : stk.top(); stk.push(i); } while (!stk.empty()) stk.pop(); int l, r; //找到右边第一个比当前值大的牛舍长度 for (int i = size - 1; i >= 0; i--) { while (!stk.empty() && areas[stk.top()] >= areas[i]) stk.pop(); right[i] = stk.empty() ? -1 : stk.top(); stk.push(i); l = left[i] == -1 ? -1 : left[i]; r = right[i] == -1 ? size : right[i]; res = max(res, (r - l - 1) * areas[i]); } return res; } };