栈和队列----求最大子矩阵的大小

Posted demrystv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈和队列----求最大子矩阵的大小相关的知识,希望对你有一定的参考价值。

求最大子矩阵的大小

  

  给定一个整型矩阵map,其中的值只有0,1两种,求全是1 的所有矩阵区域中,最大的矩形区域为1的数量。

  例如: 1  1  1  0,其中最大的矩形区域有3个1,所以返回3

  例如:

  1  0  1  1

       1  1  1  1

  1  1  1  0

  其中,最大的矩形区域有6个1,所以返回6

  

  【解析】

  首先,矩阵的行数为N,以每一行作为分割,统计以当前行作为底的情况下,每个位置往上的1 的数量,使用高度数组 height 来表示。

  其次,对于每一次分割,都利用更新后的height数组来求出每一行为底的情况下,最大的矩形的大小。这一步的实质就是在直方图中求最大矩形的面积,找到柱子左边刚比它小的柱子位置,以及右边刚比它大的柱子位置,用栈计算最快。

  

package com.test;

import java.util.Stack;

/**
 * Created by Demrystv.
 */
public class MaxSubRecSize {

    //height数组表示在以当前行作为底的情况下,每个位置往上的连续的 1 的数量
    public int maxRecSize(int[][] map){
        if (map==null || map.length==0 || map[0].length==0){
            return 0;
        }
        int maxArea = 0;
        int[] height = new int[map[0].length];
        for (int i=0; i<map.length; i++){
            for (int j=0; j<map[0].length; j++){
                height[j] = map[i][j]==0 ? 0 : height[j] + 1;
            }
            maxArea = Math.max(maxRecFromBottom(height), maxArea);
        }
        return maxArea;
    }

    //找到柱子左边刚比它小的柱子位置,以及右边刚比它大的柱子位置,用栈计算最快
    private int maxRecFromBottom(int[] height){
        if (height==null || height.length==0){
            return 0;
        }
        int maxArea = 0;
        Stack<Integer> stack = new Stack<Integer>();
        for (int i=0; i<height.length; i++){
            while (!stack.isEmpty() && height[i]<=height[stack.peek()]){
                int j = stack.pop();//不断循环,直到当前位置的值大于栈顶元素
                int k = stack.isEmpty() ? -1 : stack.peek();
                int curArea = (i - k + 1) * height[j];
                maxArea = Math.max(curArea, maxArea);
            }
            stack.push(i);
        }

     // 针对的是从栈底到栈顶一直递增的情况
while (!stack.isEmpty()){ int j = stack.pop(); int k = stack.isEmpty() ? -1 : stack.peek(); int curArea = (height.length - k + 1) * height[j]; maxArea = Math.max(curArea, maxArea); } return maxArea; } }

 


以上是关于栈和队列----求最大子矩阵的大小的主要内容,如果未能解决你的问题,请参考以下文章

01矩阵求最大子矩阵大小

数据结构--单调栈--求最大子矩阵的大小

bzoj 1047 理想的正方形

[程序员代码面试指南]栈和队列-生成窗口最大值数组(双端队列)

栈和队列----最大值减去最小值小于等于num的子数组的数量

栈和队列知识点总结