MaxArea-最大矩阵
几道最大区域(矩形)相关的题。
题目一:
container-with-most-water
Given n non-negative integers a1 , a2 , …, an , where each represents a point at coordinate (i, ai ). n vertical lines are drawn such that the two endpoints of line i is at (i, ai ) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.
题目二:
比较常见经典的一道题,求直方图的最大矩形
题目三:
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.
例如二维数组矩阵:
[[1, 1, 0, 0, 1],
[0, 1, 0, 0, 1],
[0, 0, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 1]]
输出6
下面直接上代码,代码可能更直观
import java.util.*;
public class MaxArea {
//两边和x轴构成的container最大
//height[i]之间宽为1
//初始low=0,high=height.length-1,不断淘汰短的一边(以该边为边的最大container为当前area),宽度不断减小
//height[low]>height[high]时,比当前大的area,双边肯定在 low~high-1 之间选择
//O(n)
public static int maxArea(int[] height) {
int low=0,high=height.length-1;
int area =0,max=0;
while(low<high){
area=Math.max(area,(high-low)*Math.min(height[low],height[high]));
if(height[low]>height[high])
high--;
else if(height[low]<height[high])
low++;
else{
low++;
high--;
}
}
return area;
}
//直方图最大矩形,O(n)
//主要思路:实际是中心扩展法的优化
// j<i,heights[j]遇到更小的heights[i]时,可以求以j,heights[j]为高的最大矩形(以heights[j]为限制高,向两侧扩展)
public static int largestRectangleArea(int[] heights) {
if(heights==null||heights.length==0)
return 0;
int res=0;
Stack<Integer> stack=new Stack<>();
for(int i=0;i<heights.length;i++){
while(!stack.isEmpty()&&heights[i]<=heights[stack.peek()]){
int cur=stack.pop();
int left=stack.isEmpty()?-1:stack.peek();
res=Math.max(res,(i-left-1)*heights[cur]);
}
stack.push(i);
}
while(!stack.isEmpty()){
int cur=stack.pop();
int left=stack.isEmpty()?-1:stack.peek();
res=Math.max(res,(heights.length-left-1)*heights[cur]);
}
return res;
}
//O(n*n)
//添加转换:
// 0 0 1 1 0 -> 0 0 1 1 0
// 0 0 1 1 0 -> 0 0 2 2 0
// 1 1 0 0 0 -> 1 1 0 0 0
// 1 1 1 0 0 -> 2 2 1 0 0
//再以每一行为底去求最大矩形
public static int maximalRectangle(char[][] matrix) {
if (matrix == null || matrix[0].length == 0) {
return 0;
}
int[][] dp=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(i==0){
dp[i][j]=matrix[i][j]=='1'?1:0;
}else{
dp[i][j]=matrix[i][j]=='0'?0:dp[i-1][j]+1;
}
}
int max=0;
for(int i=0;i<matrix.length;i++){
int temp=largestRectangleArea(dp[i]);
max=Math.max(max,temp);
}
return max;
}
}