package com.interview.dynamic; /** * Date 09/15/2014 * @author tusroy * * Find maximum subsquare in a matrix made up of Xs and Os such that all four sides of subsquare are Xs. It does not matter what is inside * the subsquare. All 4 sides should be made up entirely of Xs * * e.g * 0 0 0 0 0 X 0,0 0,0 0,0 0,0 0,0 1,1 * 0 X 0 X X X 0,0 1,1 0,0 1,1 1,2 2,3 * 0 X 0 X 0 X 0,0 2,1 0,0 2,1 0,0 3,1 * 0 X X X X X 0,0 3,1 1,2 3,3 1,4 4,5 * 0 0 0 0 0 0 0,0 0,0 0,0 0,0 0,0 0,0 * * Output of above program should be 3 * * Solution * Have another matrix which is capable of holding 2 values hori and ver. * Ver stores how far vertically you can see Xs. Hori stores how far horizontally you can see Xs. * Once this matrix is build look for biggest subsquare by getting min of hori and ver at each point and checking * if subsquare can be formed from value min to 1. * * Test cases: * Matrix entirely made up of Xs * Matrix entirely made up of Os * Matrix with Xs and Os but maximum subsquare is length 1 */ public class SubsquareSurrounedByXs { class Cell{ int ver; int hori; } public int findSubSquare(char input[][]){ Cell T[][] = new Cell[input.length][input[0].length]; for(int i=0; i < T.length; i++){ for(int j=0; j < T[0].length; j++){ T[i][j] = new Cell(); } } for(int i=0; i < input.length; i++){ for(int j=0; j < input[0].length; j++){ if(input[i][j] == 'X'){ if(i == 0 && j == 0){ T[i][j].hori = 1; T[i][j].ver = 1; } else if(i == 0){ T[i][j].hori = T[i][j-1].hori + 1; T[i][j].ver = 1; }else if(j == 0){ T[i][j].ver = T[i-1][j].ver +1; T[i][j].hori = 1; }else{ T[i][j].hori = T[i][j-1].hori +1; T[i][j].ver = T[i-1][j].ver + 1; } } } } for(int i=0; i < T.length; i++){ for(int j=0; j < T[0].length; j++){ System.out.print(T[i][j].ver + "," + T[i][j].hori+ " "); } System.out.println(); } //start iterating from bottom right corner and find min of hori or ver at every cell. //If this is greater than 1 then see if you can find a number between this min and 1 //such that on left's ver and top's hori is greater greater than or equal to k. int max = 1; for(int i=T.length -1; i >=0 ; i--){ for(int j= T[0].length-1 ; j >=0; j--){ if(T[i][j].ver == 0 || T[i][j].ver == 1 || T[i][j].hori ==1 ){ continue; } int min = Math.min(T[i][j].ver, T[i][j].hori); int k = 0; for(k=min; k > 1; k--){ if(T[i][j-k+1].ver >= k && T[i-k+1][j].hori >= k){ break; } } if(max < k){ max = k; } } } return max; } public static void main(String args[]){ char[][] input = {{'X','O','O','O','O','O'}, {'O','O','O','O','O','O'}, {'X','X','X','X','O','O'}, {'X','X','X','X','X','O'}, {'X','O','O','X','X','O'}, {'X','O','X','X','X','O'}}; char [][] input1 = {{'O', 'O', 'O', 'O', 'O', 'X'}, {'O', 'X', 'O', 'X', 'X', 'X'}, {'O', 'X', 'O', 'X', 'O', 'X'}, {'O', 'X', 'X', 'X', 'X', 'X'}, {'O', 'O', 'O', 'O', 'O', 'O'}, }; char [][] input2 = {{'O', 'O', 'X', 'O', 'X'}, {'O', 'X', 'X', 'O', 'X'}, {'O', 'X', 'O', 'X', 'X'}, {'X', 'X', 'X', 'X', 'X'}, {'O', 'X', 'X', 'X', 'O'}, }; SubsquareSurrounedByXs ss = new SubsquareSurrounedByXs(); System.out.println(ss.findSubSquare(input)); System.out.println(ss.findSubSquare(input1)); System.out.println(ss.findSubSquare(input2)); } }