zoukankan      html  css  js  c++  java
  • 栈和队列----求最大子矩阵的大小

    求最大子矩阵的大小

      

      给定一个整型矩阵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; } }
  • 相关阅读:
    智能指针unique_ptr记录
    ubuntu系统火狐无法播放网页视频
    javascript中json对象json数组json字符串互转及取值
    C#压缩文件
    C#异步编程
    C# POST请求 json格式
    C# Http方式下载文件到本地类
    C#中NPOI操作excel之读取和写入excel数据
    浅析C#中抽象类和接口的区别
    C#自动实现Dll(OCX)控件注册的两种方法
  • 原文地址:https://www.cnblogs.com/Demrystv/p/9302347.html
Copyright © 2011-2022 走看看