详细思路
想要在n1时间完成,枚举每一根柱子作为短板,向左右找,如果大于本身,就可以,直到遇到更短的就不行,也就是找到第一个小于本身的柱子,“找到第一个”用单调栈,用一个数组记录每一个柱子的“左边第一个”,一个数组记录“右边第一个”,如675,遇到6,栈顶-1记录,接着6push,遇到7,栈顶6记录,7push,遇到5,栈顶7pop,栈顶6pop,栈顶-1记录
精确定义
left[] 每一个柱子左侧第一个小于本身的下标
right[]每一个柱子右侧第一个大于本身的下标
stk 单调栈,栈顶是第一个小于遇到数的数的下标
class Solution { public: int largestRectangleArea(vector<int>& heights) { int n=heights.size(); vector<int>left(n,-1); vector<int>right(n,n); stack<int>stk; stk.push(-1); for(int i=0;i<n;i++){ while(1){ if(stk.top()==-1){ left[i]=-1; stk.push(i); break; } else if(heights[stk.top()]>=heights[i]){ stk.pop(); } else if(heights[stk.top()]<heights[i]){ left[i]=stk.top(); stk.push(i); break; } } } stack<int>stk1; stk1.push(n); for(int i=n-1;i>=0;i--){ while(1){ if(stk1.top()==n){ right[i]=n; stk1.push(i); break; } else if(heights[stk1.top()]>=heights[i]){ stk1.pop(); } else if(heights[stk1.top()]<heights[i]){ right[i]=stk1.top(); stk1.push(i); break; } } } int ans=0; for(int i=0;i<n;i++){ int low=(right[i]-1)-(left[i]+1)+1; ans=max(ans,low*heights[i]); } return ans; } };
踩过的坑
对于每一个数,要么是-1或n,要么是大于的需要pop,要么是第一个小于的,一个while(1)
里面3个if是很好的方法