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
[Coding Made Simple] Maximum Subsquare surrounded by 'X'