zoukankan      html  css  js  c++  java
  • [Coding Made Simple] Maximum Subsquare surrounded by 'X'

    Given a 2D matrix where every element is either ‘O’ or ‘X’, find the largest subsquare surrounded by ‘X’.

    Examples:

    Input: mat[N][N] = { {'X', 'O', 'X', 'X', 'X'},
                         {'X', 'X', 'X', 'X', 'X'},
                         {'X', 'X', 'O', 'X', 'O'},
                         {'X', 'X', 'X', 'X', 'X'},
                         {'X', 'X', 'X', 'O', 'O'},
                        };
    Output: 3
    The square submatrix starting at (1, 1) is the largest
    submatrix surrounded by 'X'
    
    Input: mat[M][N] = { {'X', 'O', 'X', 'X', 'X', 'X'},
                         {'X', 'O', 'X', 'X', 'O', 'X'},
                         {'X', 'X', 'X', 'O', 'O', 'X'},
                         {'X', 'X', 'X', 'X', 'X', 'X'},
                         {'X', 'X', 'X', 'O', 'X', 'O'},
                        };
    Output: 4
    The square submatrix starting at (0, 2) is the largest
    submatrix surrounded by 'X'

    Solution 1. O(N^4) runtime. 

    Consider every square submatrix and check whether it is only surrounded by 'X'. 

    There are O(N^3) square submatrices and each check takes O(N) time.

    Solution 2. O(N^3) runtime, O(N^2) space, using dynamic programming

    The idea is to create two auxiliary arrays hor[N][N] and ver[N][N].

    The value stored in hor[i][j] is the number of horizontal continuous ‘X’ characters from left to right till matrix[i][j] in matrix[][].

    Similarly, the value stored in ver[i][j] is the number of vertical continuous ‘X’ characters from top to bottom till matrix[i][j] in matrix[][]. 

    Once we have filled values in hor[][] and ver[][], we start from the bottommost-rightmost corner of matrix and move toward the leftmost-topmost in row by row manner.

    For every matrix[i][j] that is 'X', we compare the values of hor[i][j] and ver[i][j], and pick the smaller of two as we need a square. Let the smaller of two be ‘small’.

    At this point, we are sure that there is a right vertical line and bottom horizontal line of length at least 'small'.

    We find a bigger square if the following conditions are met.

    1. small is bigger than the current max size length;

    2. there is a left vertical line of length >= 'small';

    3. there is a top horizontal line of length >= 'small'.

    If the side length of 'small' does not generate a square, we try for small - 1. Repeat this until small is not bigger than max anymore.

     1 public class MaxSquareSubmatrix {
     2     public int getMaxSquareSubmatrixSideX(int[][] matrix) {
     3         if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
     4             return 0;
     5         }
     6         int[][] hor = new int[matrix.length][matrix[0].length];
     7         int[][] ver = new int[matrix.length][matrix[0].length];
     8         hor[0][0] = (matrix[0][0] == 'X' ? 1 : 0);
     9         ver[0][0] = (matrix[0][0] == 'X' ? 1 : 0);
    10         for(int i = 1; i < matrix.length; i++) {
    11             if(matrix[i][0] == 'O') {
    12                 ver[i][0] = 0;
    13                 hor[i][0] = 0;
    14             }
    15             else {
    16                 ver[i][0] = 1 + ver[i - 1][0];
    17                 hor[i][0] = 1;
    18             }
    19         }
    20         for(int j = 1; j < matrix[0].length; j++) {
    21             if(matrix[0][j] == 'O') {
    22                 hor[0][j] = 0;
    23                 ver[0][j] = 0;
    24             }
    25             else {
    26                 hor[0][j] = 1 + hor[0][j - 1];
    27                 ver[0][j] = 1;
    28             }
    29         }
    30         for(int i = 1; i < matrix.length; i++) {
    31             for(int j = 1; j < matrix[0].length; j++) {
    32                 if(matrix[i][j] == 'O') {
    33                     hor[i][j] = 0;
    34                     ver[i][j] = 0;
    35                 }
    36                 else {
    37                     hor[i][j] = 1 + hor[i][j - 1];
    38                     ver[i][j] = 1 + ver[i - 1][j];
    39                 }
    40             }
    41         }
    42         int max = 0;
    43         for(int i = matrix.length - 1; i >= 0; i--) {
    44             for(int j = matrix[0].length - 1; j >= 0; j--) {
    45                 if(matrix[i][j] == 'X') {
    46                     int small = Math.min(hor[i][j], ver[i][j]);
    47                     while(small > max) {
    48                         if(ver[i][j - small + 1] >= small && hor[i - small + 1][j] >= small) {
    49                             max = small;
    50                             break;
    51                         }
    52                         else {
    53                             small--;                        
    54                         }
    55                     }                    
    56                 }
    57             }
    58         }
    59         return max;
    60     }
    61 }

    Related Problems 

    Maximal Square

    Maximal Square II

  • 相关阅读:
    单选框radio 选择问题
    用户名、密码等15个常用的js正则表达式
    mysql创建远程用户并授权
    JS,Jquery获取屏幕的宽度和高度
    ThinkPHP模版时间显示
    composer启用国内镜像网站的配置更改办法
    tp6 使用全局中间件配置验证器
    tp3.2查询当前时间大于已有时间三分钟
    jquery判断手机端或者pc端
    html页面引入公共的页首和导航栏
  • 原文地址:https://www.cnblogs.com/lz87/p/7292284.html
Copyright © 2011-2022 走看看