leetcode刷题 | 直方图最大矩形面积和矩阵中最大的矩形
两道题的解法比较类似,都是使用栈作为数据结构
直方图最大矩形面积
-
对于任意的位置,想要找到以该位置为高h的矩形,可以以该位置为中心,分别向左右扩张找到以该位置为h的最大宽度。
-
如何找到最大宽度?我们只需要找到距离该位置最近的左右两侧高度小于h的柱子,这样这两根柱子之间的高度均高于h,那么这就是我们要找到的最大宽度
-
使用栈来保存数组的下标,栈中的值所对应到数组中的值,都是单调递递增的。
-
当将index放入到栈中,首先需要判断该heights[index] 是否大于heights[stack.peek()],如果大于那么可以直接入栈,如果小于那么该位置index就是heights[stack.peek()]的右边界,也就是右边第一个小于高度为h的柱子
-
然后移除栈顶,stack.pop(),这样stack.peek()就是左边第一个小于高度h的柱子,这样就找到以stack.pop()为高,index-stack.peek()-1为宽的矩形
-
然后继续比较,直到全部比较完毕
-
此时如果stack不为空的话,那么剩下的元素都是单调递增的,可以直接以stack.pop()为高,stack.size()-stack.peek()-1为宽度进行计算面积
-
最后返会res;
class Solution {
public int largestRectangleArea(int[] heights) {
Deque<Integer> deq = new ArrayDeque();
deq.push(-1);
int res = 0;
for(int i = 0;i<heights.length;i++){
while(deq.peek()!=-1 && heights[deq.peek()] > heights[i]){
res = Math.max(res,heights[deq.pop()] * (i-deq.peek()-1));
}
deq.push(i);
}
while(deq.peek()!=-1){
res = Math.max(res,heights[deq.pop()]*(heights.length-deq.peek()-1));
}
return res;
}
}
矩阵中最大的矩形
和上一道题类似
- 定义一个表示高度的数组heigths,表示从当前层到最底层连续都是1的最大高度
- 通过上一道题的计算方式进行叠加
class Solution {
public int maximalRectangle(String[] matrix) {
if (matrix.length == 0) return 0;
int res = 0;
int[] heigths = new int[matrix[0].length()];
for (String s : matrix) {
for (int i = 0;i<heigths.length;i++){
heigths[i] = s.charAt(i) == '0' ? 0:heigths[i]+1;
}
res = Math.max(res,maximalRange(heigths));
}
return res;
}
public int maximalRange(int[] heigths){
int l = heigths.length;
int[] stack = new int[l+1];
stack[0] = -1;
int index = 1;
int res = 0;
for (int i = 0;i<l;i++){
while (index > 0 && heigths[stack[index]] >= heigths[i]){
res = Math.max(res,heigths[stack[index--]]*(i-stack[index]-1));
}
stack[++index] = i;
}
while (index > 0){
res = Math.max(res,heigths[stack[index--]]*(l-stack[index]-1));
}
return res;
}
}
图片可以参考花落&月缺大佬:https://leetcode.cn/problems/0ynMMM/solution/hua-luo-yue-que-wo-zhen-de-zhen-de-nu-li-ohjt/