// A brute force solution. // n * n // iterate from n to 1. // For n, find all possible sub square Enum Color { BLACK, WHITE; } // Check sub square (left-up point [row][col], length) has all borders black // Assume square is not null, N * N matrix (N >= 1) // row and col >= 0 // row + len < square.length // col + len < square.length boolean hasBlackBorders(Color[][] square, int row, int col, int len) { for (int i = 0 ; i < len ; i ++) { if (square[row + i][col] != BLACK) // left return false; if (square[row + i][col + len - 1] != BLACK) // right return false; if (square[row][col + i] != BLACK) // up return false; if (square[row + len - 1][col + i] != BLACK) // up return false; } return true; } // O(n^) void maxSubSquareWithBlackBorders(Color[][] square) { int maxLen = square.length; for (int len = maxLen ; len > 0 ; len --) { // Given len, find possible left-up start for (int row = 0 ; row < maxLen - len + 1 ; row ++) { for (int col = 0 ; col < maxLen - len + 1 ; col ++) { if (hasBlackBorders(square, row, col, len)) { // Return the sub square with left-up point[row][col], and len. return; } } } } return null; } // A better solution? class Node { Color color; Integer maxDownRight; Integer maxUpLeft; boolean hasMaxDownRight(); } // O(n) // Populate the max down/right this node can go. void populateDownRight(Node[][] square, int row, int col) { int maxLen = square.len; if (square[row][col].color == WHITE) return; int down = 0; if (row > 0 && square[row - 1][col].hasDownRight()) down = square[row - 1][col].downRight - 1; else { for (int = row + 1 ; i < maxLen ; i ++) { down ++; } } int right = 0; // Similar to calculate down square[row][col].downRight = min(down, right); } // void populateUpLeft(Node[][] square, int row, int col) // Similar to populateDownRight O(n ^ 3) void maxSubSquareWithBlackBorders(Node[][] square) { // Populate down right for (int i = 0 ; i < maxLen ; i ++) { for (int j = 0 ; j < maxLen ; j ++) { populateDownRight(i, j); } } // Populate up left for (int i = 0 ; i < maxLen ; i ++) { for (int j = 0 ; j < maxLen ; j ++) { populateUpLeft(maxLen - i, maxLen - j); } } // Find maxOne. Node toReturn; int maxLenSeen = -1; for (int i = 0 ; i < maxLen ; i ++) { for (int j = 0 ; j < maxLen ; j ++) { int downRight = square[i][j].downRight; int possibleSqureUpLeft = square[i + downRight][j + downRight].upLeft; if (possibleSqureUpLeft >= downRight) { // We find a square matching. if (downRight > maxLenSeen) { toReturn = square[i][j]; maxLenSeen = downRight; } } } // Print toReturn with maxLenSeen. } }
时间: 2024-11-18 02:11:48