很难的问题,数组线性时间。
属于我之前说的解法的借助辅助空间。给定两个柱子,他们之间的面积由什么确定呢?没错,他们之间的距离和他们之间最矮的那个柱子的高度。我们并不知道这个柱子在什么位置,所以只能遍历,这个复杂度就上去了。那有没有一个方法避免找中间小柱子呢?先想什么情况下不用找。除非你知道枚举出两个位置之间的柱子都比现在这个长。所以想到了用一个栈来保存较长的那些柱子编号。需要保证的一件事是栈里面的柱子高度一定是递增的,每次计算面积的时候是从当前位置往前计算的,计算一次弹出一次,每次都使用栈顶的高度,就像每次都计算被两个较矮柱子包裹的较高柱子们的面积。
整个算法的过程是这样的,一开始栈为空,从左侧开始扫,如果栈空,或者当前扫到的位置比栈顶的高度高,直接把编号入栈。为什么入栈的是编号而不是高度呢?因为求的是面积啊,如果只压入面积,每次得到的就少了一维的信息啊亲。如果当前扫到的柱子比栈顶的低怎么办?出栈。注意在出栈时计算面积是不把当前扫到的位置计算在内的,每次都是把栈顶高度当做最低高度,计算从栈顶位置到当前位置前一位置的面积。这个出栈操作到什么时候呢?到栈空或者当前位置的高度终于比栈顶的高了。扫完一遍之后,栈很可能非空,但里面的柱子肯定是递增的,直接执行一次出栈过程就可以了。
算法为什么是线性的?感觉过程好复杂。不复杂,每个柱子一定只进栈和出栈一次,想起matrix67对这种问题的比喻,100天,我每天谈一个美眉,那么我可能失恋200次吗?大神就是大神。
class Solution { public: int largestRectangleArea(vector<int> &height) { int res = 0, tpres, tp; int msize = height.size(); int i = 0; stack<int> s; while(i<msize){ if(s.empty()||height[s.top()]<=height[i]){ s.push(i++); }else{ tp = s.top(); s.pop(); tpres = height[tp]*(s.empty()?i:i-s.top()-1); res = max(tpres, res); } } while(!s.empty()){ tp = s.top(); s.pop(); tpres = height[tp]*(s.empty()?i:i-s.top()-1); res = max(tpres, res); } return res; } };
leetcode第一刷_Largest Rectangle in Histogram,布布扣,bubuko.com
时间: 2024-10-24 10:45:52