Google – Image And
两个黑白image, 用2D matrix表示,matrix的边长为2^k。 要求设计一个数据结构来表示image,尽量做到space最少。然后对两个Image做And,黑黑得黑,白白得白,黑白得白。
[Solution]
看到2^k边长的条件,考点是QuadTree肯定错不了。
Quad tree既可以省空间,也可以省时间。因为如果某一大块下面所有的cell都是黑(或者都是白),那么它就不需要任何sub tree了。做And的时候也可以直接返回,要比O(n^2) Brute force一个cell一个cell的做And快很多。
Read full article from Google – Image And
两个黑白image, 用2D matrix表示,matrix的边长为2^k。 要求设计一个数据结构来表示image,尽量做到space最少。然后对两个Image做And,黑黑得黑,白白得白,黑白得白。
[Solution]
看到2^k边长的条件,考点是QuadTree肯定错不了。
Quad tree既可以省空间,也可以省时间。因为如果某一大块下面所有的cell都是黑(或者都是白),那么它就不需要任何sub tree了。做And的时候也可以直接返回,要比O(n^2) Brute force一个cell一个cell的做And快很多。
class TNode { public char val; public TNode leftTop; public TNode rightTop; public TNode leftBot; public TNode rightBot; public TNode(char val) { this.val = val; }}class Solution { public TNode buildTree(char[][] image) { int n = image.length; return buildTree(image, 0, 0, n - 1, n - 1); } public TNode buildTree(char[][] image, int row1, int col1, int row2, int col2) { if (row1 < 0 || row1 >= image.length || row2 < 0 || row2 >= image.length || col1 < 0 || col1 >= image.length || col2 < 0 || col2 >= image.length || row1 > row2 || col1 > col2) { return null; } if (row1 == row2 && col1 == col2) { TNode result = new TNode(image[row1][col1]); if (image[row1][col1] == '1') { result.val = '1'; } else { result.val = '0'; } return result; } int midX = row1 + (row2 - row1) / 2; int midY = col1 + (col2 - col1) / 2; TNode root = new TNode('#'); TNode leftTop = buildTree(image, row1, col1, midX, midY); TNode rightTop = buildTree(image, row1, midY + 1, midX, col2); TNode leftBot = buildTree(image, midX + 1, col1, row2, midY); TNode rightBot = buildTree(image, midX + 1, midY + 1, row2, col2); if (leftTop.val == '1' && rightTop.val == '1' && leftBot.val == '1' && rightBot.val == '1') { root.val = '1'; } else if (leftTop.val == '0' && rightTop.val == '0' && leftBot.val == '0' && rightBot.val == '0') { root.val = '0'; } else { root.leftTop = leftTop; root.rightTop = rightTop; root.leftBot = leftBot; root.rightBot = rightBot; } return root; } public TNode imageAnd(TNode root1, TNode root2) { TNode root = new TNode('#'); if (root1 == null && root2 == null) { return null; } if (root1.val == '1' && root2.val == '1') { return new TNode('1'); } else if (root1.val == '0' || root2.val == '0') { return new TNode('0'); } else if (root1.val == '#' && root2.val == '1') { root.leftTop = imageAnd(root1.leftTop, root2); root.rightTop = imageAnd(root1.rightTop, root2); root.leftBot = imageAnd(root1.leftBot, root2); root.rightBot = imageAnd(root1.rightBot, root2); } else if (root1.val == '1' && root2.val == '#') { root.leftTop = imageAnd(root1, root2.leftTop); root.rightTop = imageAnd(root1, root2.rightTop); root.leftBot = imageAnd(root1, root2.leftBot); root.rightBot = imageAnd(root1, root2.rightBot); } else { root.leftTop = imageAnd(root1.leftTop, root2.leftTop); root.rightTop = imageAnd(root1.rightTop, root2.rightTop); root.leftBot = imageAnd(root1.leftBot, root2.leftBot); root.rightBot = imageAnd(root1.rightBot, root2.rightBot); } return root; } public void toMatrix(TNode root, char[][] matrix, int row1, int col1, int row2, int col2) { if (root == null) { return; } if (root.val == '1' || root.val == '0') { for (int i = row1; i <= row2; i++) { for (int j = col1; j <= col2; j++) { matrix[i][j] = root.val; } } } else { int midX = row1 + (row2 - row1) / 2; int midY = col1 + (col2 - col1) / 2; toMatrix(root.leftTop, matrix, row1, col1, midX, midY); toMatrix(root.rightTop, matrix, row1, midY + 1, midX, col2); toMatrix(root.leftBot, matrix, midX + 1, col1, row2, midY); toMatrix(root.rightBot, matrix, midX + 1, midY + 1, row2, col2); } }}