I got a DP solution first which is O(n^2). Apparently it is not a optimized one - think about: it is linear value space. There must be O(n) solution.
And yes there is: http://fisherlei.blogspot.com/2012/12/leetcode-largest-rectangle-in-histogram.html
It reminds me the mono-queue optimization upon DP - it is said to be even out-of-scope of IOI.. Precisely that is not a typical mono-queue style used. The mono-queue maintanence is tricky: if new height is less than top, we pop out all anti-mono elements and calculate corresponding areas - to make sure the queue is monotonous.
But how to conduct yourself to the wonderland you are longing for? Like this:
O(n^3) solution is direct -> Has duplicated calculation? Use DP -> O(n^2) -> is it linear space? think about MonoQ -> figure out how to maintanent MonoQ -> O(n)
Please keep the animated pictures of the whole procedure in mind. That helps.
I put comments:
class Solution { public: int largestRectangleArea(vector<int> &height) { int cnt = height.size(); if(cnt == 0) return 0; if(cnt == 1) return height[0]; int max = std::numeric_limits<int>::min(); stack<int> stk; // store indices height.push_back(0); // as sentinel for wrapping up everything for(int i = 0; i < height.size(); i ++) { if (stk.empty() || height[i] > height[stk.top()]) { stk.push(i); // keep growing the non-descending mono-queue } else { int lastInx = stk.top(); stk.pop(); int lastH = height[lastInx]; max = std::max(max, lastH * (stk.empty() ? i - (-1) - 1 : i - stk.top() - 1)); // expands to the left as much as possible i --; // going back for all heights that are higher than height[i] } } return max; } };
TO BE REVISED LATER