Leetcode 84. Largest Rectangle in Histogram & 85. Maximal Rectangle
来源:互联网 发布:caffe的test iter 编辑:程序博客网 时间:2024/06/12 20:24
84. Largest Rectangle in Histogram
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the
histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]
.
The largest rectangle is shown in the shaded area, which has area = 10
unit.
For example,
Given heights = [2,1,5,6,2,3]
,
return 10
.
老实讲,挺怕这种histogram的题的,碰见的逻辑都很强大。什么俩指针,相等就同时向中间移动;或者用stack什么的。就是说这种题给出来很直观,但是算法的都比较不容易想。
想了一会果断不会,然后发现了一篇非常好的文章:http://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html
这篇作者讲的非常详细。下面就把碰到的一些细节说出来,吐槽:每次debug碰到小细节问题都要浪费好几个小时蛋疼。。
思路是这样:
比如图中的5,6最大。5的左边全部小于5;6的右边全部小于6。作者的思路是维护一个stack, 使得当前遍历的元素cur一定要大于数组的peek()值。这样数组中的元素是递增的。
每当我们碰到一个小于的元素(这样就保证右边小于了,peek()是last element),一直pop stack直到第一个元素小于了当前的值(这样就保证了左边小于)。于是要做的就是计算出栈这几个元素的结果。
为了清空stack需要额外在数组尾部加入一个0。为了计算方便,stack中存入的是index。
需要注意以下几点:
1. 比如出5, 6。先出6,算一次;然后出5, 5,6算一次。
2. width应该等于 st.isEmpty() ? i : i - st.peek() - 1。这个非常重要。stack不空的时候不等于i-stack last pop()。
反例就是这个[4,2,0,3,2,5]。先4,碰到2输出4,2入栈。然后碰到0,2输出计算,0入栈。然后碰到3入栈,在碰到2,输出3计算,2入栈。这时候栈里面是【0, 2】。然后碰到5入
栈,最后碰到添加的0,出栈的是5和2!!!! 6-2-1=3 * 2 =6。相当于index 2处的0做了左边界,添加的0做了右边界,然后计算了中间的值。如果用 i-last出栈index,则只能得到
(6-4)*2=4,就错了。
public class Solution { public int largestRectangleArea(int[] heights) { Stack<Integer> st = new Stack<Integer>(); int n = heights.length; int res = 0; for(int i=0; i<=n; i++){ int cur = i==n ? 0: heights[i]; while(!st.isEmpty() && heights[st.peek()]>cur){ int h = st.pop(); res = Math.max(res, heights[h]* (st.isEmpty() ? i : i - st.peek()-1)); // i - h wrong, [4,2,0,3,2,5] if the last matrix is from 3->5 with height of 2, here peek() gives the boundary, if // use the index last popped by stack, we will not take care of 3. // so the stack guarantees the index we have must be shorter than the index we are calculating now. // in this case, index is 5, height is 2, the stack have one element 2, the height of which is 0. // the stack tells us when we will find the first element that is shorter than cur! // we already make sure the current i index has a smaller value than cur (if larger than current i, pop) } st.push(i); // save index for calculation convenience } return res; }}
网上有人用数组实现了stack,运行时间更快:
// The classic stack solution is simpler. However, using collection will be slower. Here is an implementation using int array to simulation a stack. The run time is 5 ms.public class Solution { public int largestRectangleArea(int[] h) { int n = h.length; int max = 0; int[] stack = new int[n + 1]; int is = -1; for (int i = 0; i <= n; i++) { int height = (i == n) ? 0 : h[i]; while (is != -1 && height < h[stack[is]]) { int hh = h[stack[is--]]; int width = (is == -1) ? i : i - 1 - stack[is]; max = Math.max(max, hh * width); } stack[++is] = i; } return max; }}
85. Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
解法一:
将该2D数组化成直方图数组。每一行对应一个直方图,直方图的每列高度是以该点开始,向上连续1的数量。你要问我为啥..我也不知道 然后这道题就相当于84那题,给了m行个直方图,求这m个直方图中的最大值。
public class Solution { // 33ms public int maximalRectangle(char[][] matrix) { if(matrix==null||matrix.length==0||matrix[0].length==0) return 0; int[][] hist = new int[matrix.length][matrix[0].length]; for(int i=0; i<matrix.length; i++){ for(int j=0; j<matrix[0].length; j++){ if(matrix[i][j]=='0') hist[i][j]=0; else{ hist[i][j]=1; int m=i-1; while(m>=0 && matrix[m][j]=='1'){ hist[i][j]++; m--; } } } } int res=0; for(int i=0; i<hist.length; i++){ res = Math.max(res, findMax(hist[i])); } return res; } public int findMax(int[] hist){ Stack<Integer> st = new Stack<Integer>(); int res=0; int cur; for(int i=0; i<=hist.length; i++){ if(i==hist.length) cur=0; else cur=hist[i]; while(!st.isEmpty() && hist[st.peek()]>cur){ int index = st.pop(); int width = st.isEmpty() ? i : i - st.peek() - 1; res = Math.max(res, hist[index] * width); } st.push(i); } return res; }}
解法二:
dp。
http://liangjiabin.com/blog/2015/04/leetcode-maximal-rectangle.html
题目的Tags里给出了动态规划,那么这道题能不能用动态规划解呢?这道题与传统的动规有点不一样,传统的动规只需要从左上角一直遍历到右下角,每往下一步往右一步都由上面和左边的状态来决定当前的状态,最右下角便是最优解。而这道题求最大矩形面积,却需要从上大小,从左到右一次,从右到左一次,保存两个方向的状态。具体来说,从上到下,与上面解法类似,对于每一层i,记录每个点matrix[i][j]正上面字符1的连续高度height[j];从左到右,记录高度为height[j]的矩形左边的起始位置left[j];从右到左,记录高度为height[j]的矩形右边的结束为止;那么matrix[i][j]这个点处的最大矩形面积就是(right[j]-left[j])*height[j]。
public class Solution { // 13ms public int maximalRectangle(char[][] matrix) { if(matrix==null||matrix.length==0||matrix[0].length==0) return 0; int[][] hist = new int[matrix.length][matrix[0].length]; for(int i=0; i<matrix.length; i++){ for(int j=0; j<matrix[0].length; j++){ if(matrix[i][j]=='0') hist[i][j]=0; else{ hist[i][j]=1; int m=i-1; while(m>=0 && matrix[m][j]=='1'){ hist[i][j]++; m--; } } } } int res=0; for(int i=0; i<hist.length; i++){ res = Math.max(res, findMax(hist[i])); } return res; } public int findMax(int[] hist){ Stack<Integer> st = new Stack<Integer>(); int res=0; int cur; for(int i=0; i<=hist.length; i++){ if(i==hist.length) cur=0; else cur=hist[i]; while(!st.isEmpty() && hist[st.peek()]>cur){ int index = st.pop(); int width = st.isEmpty() ? i : i - st.peek() - 1; res = Math.max(res, hist[index] * width); } st.push(i); } return res; }}
- Leetcode 84. Largest Rectangle in Histogram & 85. Maximal Rectangle
- leetcode 84.Largest Rectangle in Histogram, 85.Maximal Rectangle
- [LeetCode] Largest Rectangle in Histogram、Maximal Rectangle
- LeetCode Largest Rectangle in Histogram&&Maximal Rectangle
- 【leetCode】Largest Rectangle in Histogram&Maximal Rectangle
- leetcode 84|85. Largest Rectangle in Histogram | Maximal Rectangle
- Leetcode——84.Largest Rectangle in Histogram && 85.Maximal Rectangle
- Leetcode:Largest Rectangle in Histogram与Maximal Rectangle
- [LeetCode 84, 85]Largest Rectangle in Histogram / Maximal Rectangle
- [LeetCode]84Largest Rectangle in Histogram && 85Maximal Rectangle
- Largest Rectangle in Histogram & Maximal Rectangle
- Largest Rectangle in Histogram&&Maximal Rectangle
- leetcode: Largest Rectangle in Histogram,Maximal Square,Maximal Square问题
- [Leetcode] 84. Largest Rectangle in Histogram
- LeetCode --- 84. Largest Rectangle in Histogram
- [LeetCode]*84.Largest Rectangle in Histogram
- [leetcode] 84.Largest Rectangle in Histogram
- [leetcode] 84. Largest Rectangle in Histogram
- ssm(spring+springMVC+Mybatis)框架 集成Quartz(定时任务框架)
- Mapreduce和HBase新版本整合之WordCount计数案例
- 文章标题
- 双栈排序
- TimesTen的操作系统,数据库和虚拟化软件支持列表
- Leetcode 84. Largest Rectangle in Histogram & 85. Maximal Rectangle
- Java 多线程(六) synchronized关键字详解
- 基于AT91SAM9261EK的嵌入式Linux2.6.32+Yaffs2 根文件系统移植成功
- Spark Streaming+Kafka+Hive+JSON实时增量计算示例
- eclipse安装maven插件
- POJ 1039Pipe(直线相交)
- Dhroid框架六大组件之Ioc容器【下】
- PPT怎么制作盗墓笔记的文字效果?
- 遍历创建进程、创建线程、加载模块的回调函数