题目
给定一个整形矩阵map,其中的值只有0和1两种,求其中全是1的所有矩阵区域中,最大的矩阵型区域为1的数量。
Example:
- 1 1 1 0
Return : 3
Example:
- 1 0 1 1
- 1 1 1 1
- 1 1 1 0
Return: 6
解析: 将整个矩阵可以看成一个直方图
第一行为底部: 构成 1 0 1 1 ,其中第一列高为1,依次 0 1 1
第二行为底部:构成四列高分别为 2 1 2 2的直方图。
第三行为底部构成四列高为 3 2 3 0 的脂肪图(最后一行的最后一个高为0,无法和前面的构成直方图)
我们只需要求这三个直方图求最大矩形的面积即可!问题转化为求直方图中最大矩形的面积
java代码如下
package com.gcp.www;
import java.util.Stack;
public class MaxMatrix {
public int maxSize(int[][] map){
int[] heights = new int[map[0].length];
int maxSize = 0;
for(int i = 0 ; i < map.length ; i++){
for(int j = 0 ; j < map[i].length;j++){
if(map[i][j] == 0){
heights[j] = 0;
}else if(map[i][j] == 1){
heights[j] = heights[j] + 1;
}
}
//计算该heights矩阵构成的最大面积
maxSize = maxArea(heights);
}
return maxSize;
}
private int maxArea(int[] heights){
int maxArea = 0;
Stack<Integer> stack = new Stack();
for(int i = 0 ; i < heights.length;i++){
while(true){
if(stack.isEmpty() || heights[i] > heights[stack.peek()] ){
stack.push(i);
break;
}else{
//判断当前要压入的高度是否小于当前要栈顶要压入的高度
if(heights[i] <= heights[stack.peek()]){
int pop = stack.pop();
int k = stack.isEmpty()?-1:stack.peek();
int area = (i- k -1) * heights[pop];
maxArea = Math.max(maxArea, area); //获取最大面积
}
}
}
}
while(!stack.isEmpty()){
int pop = stack.pop();
int k = stack.isEmpty()?-1:stack.peek();
int area = (heights.length - k - 1)*heights[pop];
maxArea = Math.max(maxArea, area); //获取最大面积
}
return maxArea;
}
public static void main(String[] args) {
int[][] dp = {{1,1,1,1},{1,1,1,1},{1,1,1,0}};
int result = new MaxMatrix().maxSize(dp);
System.out.println(result);
}
}
注:由于没有测试太多的用例,可能存在程序有一些小错误出现误判的情况,只要知道相应的思想即可根据自己的代码写出答案。