package com.interview.books.ccinterview;
/**
* Created_By: stefanie
* Date: 14-12-14
* Time: 下午3:58
*/
public class CC37_MaxBlackBorderSubsquare {
class Subsquare {
int row;
int col;
int size;
Subsquare(int row, int col, int size) {
this.row = row;
this.col = col;
this.size = size;
}
}
class CountCell {
int rightOnes = 0;
int belowOnes = 0;
CountCell(int rightOnes, int belowOnes) {
this.rightOnes = rightOnes;
this.belowOnes = belowOnes;
}
}
public Subsquare findMax(int[][] matrix){
CountCell[][] preprocessed = processSquare(matrix); //Optimize
for(int len = matrix.length; len >= 1; len--){
int end = matrix.length - len + 1;
for(int row = 0; row < end; row++){
for(int col = 0; col < end; col++){
if(checkBorder(preprocessed, row, col, len)) return new Subsquare(row, col, len);
}
}
}
return null;
}
// preprocess by find how many continious 1 in right or below,
// when check bolder, just need check diff if 1's count in each edge == size.
private CountCell[][] processSquare(int[][] matrix) {
CountCell[][] preprocessed = new CountCell[matrix.length][matrix.length];
for(int r = matrix.length - 1; r >= 0; r--){
for(int c = matrix.length - 1; c >= 0; c--){
int right = 0;
int below = 0;
if(matrix[r][c] == 1){
right++;
below++;
if(c + 1 < matrix.length) right += preprocessed[r][c+1].rightOnes;
if(r + 1 < matrix.length) below += preprocessed[r+1][c].belowOnes;
}
preprocessed[r][c] = new CountCell(right, below);
}
}
return preprocessed;
}
private boolean checkBorder(CountCell[][] preprocessed, int row, int col, int len){
if(preprocessed[row][col].rightOnes < len) return false; //topLeft
if(preprocessed[row][col].belowOnes < len) return false;
if(preprocessed[row][col + len - 1].belowOnes < len) return false; //topRight
if(preprocessed[row + len - 1][col].rightOnes < len) return false; //bottomLeft
return true;
}
public static void main(String[] args){
CC37_MaxBlackBorderSubsquare finder = new CC37_MaxBlackBorderSubsquare();
int[][] matrix = new int[][]{
{1,0,0,1,1,1},
{1,0,1,1,0,1},
{1,1,1,1,1,1},
{0,1,0,0,1,1},
{1,1,0,1,1,1},
{0,1,1,1,1,1}
};
Subsquare square = finder.findMax(matrix);
System.out.println(square.row + ", " + square.col + ", size: " + square.size);
//2, 1, size: 4
matrix = new int[][]{
{1,0,0,1,1,1},
{1,0,1,1,0,1},
{1,1,1,1,1,1},
{0,1,0,0,1,1},
{1,1,0,1,0,1},
{0,1,1,1,1,1}
};
square = finder.findMax(matrix);
System.out.println(square.row + ", " + square.col + ", size: " + square.size);
//0, 3, size: 3
}
}