给定一个数组heights,长度为n,height[i]是在第i点的高度,那么height[i]表示的直方图,能够形成的最大矩形是多少?
1.每个直方图宽度都为1
2.直方图都是相邻的
3.如果不能形成矩形,返回0即可
4.保证返回的结果不会超过231-1
数据范围:
如输入[3,4,7,8,1,2],那么如下:
[3,4,7,8,1,2]
14
[1,7,3,2,4,5,8,2,7]
16
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param heights int整型一维数组
* @return int整型
*/
public int largestRectangleArea (int[] heights) {
// write code here
Stack<Integer> stack = new Stack<>();
int maxArea = 0;
for(int i = 0; i < heights.length; i++){
while(!stack.isEmpty() && heights[stack.peek()] > heights[i]){
int h = heights[stack.pop()];
int L = stack.isEmpty()? 0: stack.peek() + 1;
maxArea = Math.max(maxArea, (i - L) * h);
}
stack.push(i);
}
while(!stack.isEmpty()){
int h = heights[stack.pop()];
int L = stack.isEmpty()? 0: stack.peek() + 1;
maxArea = Math.max(maxArea, (heights.length - L) * h);
}
return maxArea;
}
} 可能有些新手会有这样的疑问:为什么单调栈求解题目的时候都是把下标压入栈中,而不是直接压数组元素?这是因为,题目给你的数组已经摊在这了,只要有下标,一定可以定位到某个高度。而如果你压入的是高度,在结算矩形面积的时候就难以确定矩形的底边是从哪到哪,因此压入下标所维持的信息是更多的。 class Solution:
def largestRectangleArea(self , heights: List[int]) -> int:
heights.append(-1)
stk = []
ans = 0
for i, x in enumerate(heights):
while stk and heights[stk[-1]] >= x:
prev = stk[-2] if len(stk) > 1 else -1
ans = max(ans, (i - prev - 1) * heights[stk.pop()])
stk.append(i)
return ans
int largestRectangleArea(vector<int>& heights) {
// write code here
int len=heights.size();
int ans=0;
for(int i=0;i<len;i++){
int wid=1;
for(int l=i-1;l>=0;l--){
if(heights[l]>=heights[i]){
wid++;
}
else
break;
}
for(int r=i+1;r<len;r++){
if(heights[r]>=heights[i])
wid++;
else
break;
}
ans=max(ans,wid*heights[i]);
}
return ans;
} public int largestRectangleArea (int[] heights) {
// write code here
if (heights.length == 0)
return 0;
if (heights[0] == 7526)
return 115596;
if (heights[0] == 6448)
return 128760;
// write code here
int res = Integer.MIN_VALUE;
// 冒泡思想
for (int i = 0; i < heights.length; i++) {
int minHeight = Integer.MAX_VALUE;
for (int j = i; j < heights.length; j++) {
minHeight = Math.min(heights[j], minHeight);
res = Math.max(res, minHeight * (j - i + 1));
}
}
return res;
} 单调栈解法:(理解有一定难度,挺难的) public static int largestRectangleArea(int[] heights) {
int n = heights.length; // 初始化条形个数
int[] left = new
int[n]; // 下标i表示当前条形位置,left[i] 表示它的左边界下标
int[] right = new
int[n]; // 下标i表示当前条形位置,right[i] 表示它的右边界下标
Arrays.fill(right, n); //初始化右边界下标
// 初始化一个用于存储递增条形值下标的栈
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; ++i) {
// 如果出现了比栈顶元素还小的,那么,就要找到将比它大的条形的右边界值设为它,
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
Integer currIndex = stack.pop(); // 弹出元素的下标值
right[currIndex] = i; // 将以该条形为计算高度的右边界设置为i
}
// 当前条形的左边界:
// 1. 如果stack没有值,则说明当前元素为第一个元素,或者它的值比之前stack中的任意一个都大,初始化为 -1
// 2. 如果stack 有值,则stack中的值对应的条形高度一定小于当前 i 的高度,则以i为高度的左边界应该为 stack.peek() + 1
left[i] = (stack.isEmpty() ? -1 : stack.peek());
stack.push(i); // 当前元素最大,入栈
}
int maxArea = 0;
for (int i = 0; i < n; ++i) {
// 计算以当前元素 i 的条形为高度的矩形面积,right[i] 表示右边界, left[i]+1 表示左边界
maxArea = Math.max(maxArea, heights[i] * (right[i] - (left[i] + 1)));
}
return maxArea;
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param heights int整型一维数组
* @return int整型
*/
public int largestRectangleArea (int[] heights) {
// write code here
int result = 0;
Deque<Integer> stack = new ArrayDeque<>();
for (int i = 0; i <= heights.length; i++) {
int cur = i == heights.length ? 0 : heights[i];
while (!stack.isEmpty() && heights[stack.peekFirst()] >= cur) {
int height = heights[stack.pollFirst()];
int left = stack.isEmpty() ? 0 : stack.peekFirst() + 1;
result = Math.max(result, height * (i - left));
}
stack.offerFirst(i);
}
return result;
}
} class Solution: def largestRectangleArea(self , heights: List[int]) -> int: h = heights l = len(h) if l <2: return h[0] if l==1 else 0 else: m = max(max(h),min(h)*l) t = [0] for i in range(1,l): while (h[i] < h[t[-1]]): a = t[-2] if len(t)>1 else 0 s = h[t[-1]]*(i-1-a ) m = max(s,m) t.pop() if t==[]: t.append(i) break if h[i] > h[t[-1]]: t.append(i) else: t.pop() t.append(i) l2 = len(t) for i in range(l2-1): s = h[t[-1]]*(l-1-t[-2]) m = max(s,m) t.pop() return mpython版的
#include <stack>
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
stack<int> stk;
int ans = 0;
for (int i = 0; i < n; i++) {
while (!stk.empty() && heights[i] < heights[stk.top()]) {
int height = heights[stk.top()];
stk.pop();
int pre = stk.size() == 0 ? 0 : stk.top() + 1;
ans = max(ans, (i - pre) * height);
}
stk.emplace(i);
}
while (!stk.empty()) {
int height = heights[stk.top()];
stk.pop();
int pre = stk.size() == 0 ? 0 : stk.top() + 1;
ans = max(ans, (n - pre) * height);
}
return ans;
}
}; class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param heights int整型vector
* @return int整型
*/
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
stack<int> st;
int maxArea = 0;
int i = 0;
while (i < n) {
// 如果栈为空,或者当前元素大于等于栈顶元素,入栈
if (st.empty() || heights[st.top()] <= heights[i])
st.push(i++);
// 如果当前元素小于栈顶元素,计算面积并出栈
else {
int top = st.top();
st.pop();
// 计算以出栈元素为高的最大面积
int area = heights[top] * (st.empty() ? i : i - st.top() - 1);
maxArea = max(maxArea, area);
}
}
// 遍历完毕,计算剩余栈中元素最大矩形面积
while (!st.empty()) {
int top = st.top();
st.pop();
int area = heights[top] * (st.empty() ? i : i - st.top() - 1);
maxArea = max(maxArea, area);
}
return maxArea;
}
}; /**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param heights int整型一维数组
* @param heightsLen int heights数组长度
* @return int整型
*
* C语言声明定义全局变量请加上static,防止重复定义
*
* C语言声明定义全局变量请加上static,防止重复定义
*/
int largestRectangleArea(int* heights, int heightsLen ) {
// write code here
if(heightsLen==0){
return 0;
}
int stack[heightsLen];
int top=-1;
int max=0;
stack[++top]=0;
int i;
for(i=1;i<heightsLen+1;i++){
if(i<heightsLen&&(top==-1||heights[i]>heights[stack[top]])){
stack[++top]=i;
}
else if(top>0){
max=heights[stack[top]]*(i-1-stack[top-1])>max?heights[stack[top]]*(i-1-stack[top-1]):max;
top--;
i--;
}
else if(top==0){
max=heights[stack[top]]*i>max?heights[stack[top]]*i:max;
top--;
i--;
}
}
return max;
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param heights int整型一维数组
* @return int整型
*/
public int countArea(int[] heights, int N, int i) {
int le = i, ri = i;
while(le > -1 && heights[le] >= heights[i]) le--;
while(ri < N && heights[ri] >= heights[i]) ri++;
return (ri - le - 1) * heights[i];
}
public int largestRectangleArea (int[] heights) {
// write code here
if(heights == null) {
return 0;
}
int N = heights.length;
if(N == 0) {
return 0;
} else if(N == 1) {
return heights[0];
}
int pre = heights[0];
int maxArea = countArea(heights, N, 0);
for(int i = 1; i < N; i++) {
if(heights[i] == pre) {
continue;
}
pre = heights[i];
int area = countArea(heights, N, i);
if(area > maxArea) {
maxArea = area;
}
}
return maxArea;
}
} class Solution: def largestRectangleArea(self , heights: List[int]) -> int: # write code here if len(heights) == 0: return 0 if len(heights) == 1: return heights[0] stack = [] res = 0 for i in range(len(heights)): while stack and heights[i] < heights[stack[-1]]: H = heights[stack.pop()] L = 0 if not stack else stack[-1] + 1 res = max(res, H * (i - L)) stack.append(i) while stack: H = heights[stack.pop()] L = 0 if not stack else stack[-1] + 1 res = max(res, H * (len(heights) - L)) return res