Largest Rectangle in Histogram
Brute Force
计算每两个index之间的rectangle O(n^2)
Python TLE
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
n = len(heights)
res = 0
for i in range(n):
minV = heights[i]
for j in range(i, n):
minV = min(minV, heights[j])
res = max(minV*(j-i+1), res)
return res
解法一 brute force + pruning optimize
如何pruning?
只遍历局部峰值。什么是局部峰值?下一个index高度没有现在的高,就是局部峰值了。
For example, [2,1,5,6,4,3] -> 2, 6, 4在这里都是局部峰值。
为什么可以这样?
如果下一个index高度比现在高,现在可以组成的长方形,可以包括在下一个index里。
1, 5, 6为升序,我们可以省略1, 5
1 - (2, 1)形成的长方形可以包括在(2,1,5,6)里
5 - (1, 5) 形成的长方形可以包括在(1, 5, 6)里
(2, 1, 5)形成的长方形可以包括在(2,1,5,6)里
Python
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
n = len(heights)
res = 0
for i in range(n):
if i+1<n and heights[i+1]>=heights[i]: continue
minV = heights[i]
for j in range(i, -1, -1):
minV = min(minV, heights[j])
res = max(res, minV*(i-j+1))
return res
C++
class Solution {
public:
int largestRectangleArea(vector<int>& height) {
int maxV = 0;
for(int i =0; i< height.size(); i++){
if(i+1 < height.size()&& height[i] <= height[i+1])
continue;
int minV = height[i];
for(int j =i; j>=0; j--){
minV = min(minV, height[j]);
int area = minV*(i-j+1);
maxV = max(maxV, area);
}
}
return maxV;
}
};
解法二 DP
基本思想是找到以每一个index高度为高的最大rectangle。遍历每一位,寻找每一位的最左和最右边界。
Python
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
if not heights: return 0
n = len(heights)
leftLess = [0]*n
leftLess[0] = -1
for i in range(1, n):
p = i-1
while p>=0 and heights[p]>=heights[i]:
p = leftLess[p]
leftLess[i] = p
rightLess = [0]*n
rightLess[n-1] = n
for j in range(n-2, -1, -1):
p = j+1
while p<n and heights[p]>=heights[j]:
p = rightLess[p]
rightLess[j] = p
res = 0
for i in range(n):
res = max(res, heights[i]*(rightLess[i]-leftLess[i]-1))
return res
C++
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if(heights.empty()) return 0;
int n = heights.size(), res=0;
int lessFromLeft[n] = {0};
int lessFromRight[n] = {0};
lessFromLeft[0] = -1;
lessFromRight[n-1] = n;
for(int i=1;i<n;i++){
int p = i-1;
while(p>=0 && heights[p]>=heights[i]){
p = lessFromLeft[p];
}
lessFromLeft[i] = p;
}
for(int i=n-2;i>=0;i--){
int p = i+1;
while(p<n && heights[p]>=heights[i]){
p = lessFromRight[p];
}
lessFromRight[i] = p;
}
for(int i=0;i<n;i++){
res = max(res, heights[i]*(lessFromRight[i]-lessFromLeft[i]-1));
}
return res;
}
};
Similar Question:
LeetCode - 238. Product of Array Except Self
解法三 Stack
方法和上面相同,只不过通过stack来实现
Python
class Solution(object):
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
heights.append(0)
stack = [-1]
res = 0
for i in range(len(heights)):
while heights[i]<heights[stack[-1]]:
h = heights[stack.pop()]
w = i-stack[-1]-1
res = max(res, h*w)
stack.append(i)
return res
C++
class Solution {
public:
int largestRectangleArea(vector<int> &height) {
int res = 0;
stack<int> st;
height.push_back(0);
for (int i = 0; i < height.size(); ++i) {
if (st.empty() || height[st.top()] < height[i]) {
st.push(i);
} else {
int cur = st.top(); st.pop();
res = max(res, height[cur] * (st.empty() ? i : (i - st.top() - 1)));
--i;
}
}
return res;
}
};
Similar Question:
LeetCode - 739. Daily Temperatures