Showing posts with label Quadtrees. Show all posts
Showing posts with label Quadtrees. Show all posts

Recover Picture - Google


https://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=456029

还原黑白图片

给一个只有黑白pixel的图片,调用给定的两个method,把图片重新画出来。两个method分别是:int readSource(int x1, int y1, int x2, int y2)和void writeTarget(int x1, int y1, int x2, int y2);
补充
题目意思大概是要利用第一个method来判断坐标区域内是否为全黑全白或者都有,三种情况会分别返回1,-1,0。第二个method是在坐标区域内画图,但是画出来的图只有黑色。
·LC类似题目:427  construct quad tree

思路:
  1. dfs解法,先检查当前square是否全黑全白,如果全黑,涂黑当前区域,返回,如果全白,返回,如果有黑有白,按照construct quad tree的的思路分成4块递归


LeetCode 558 - Quad Tree Intersection


https://leetcode.com/problems/quad-tree-intersection/
A quadtree is a tree data in which each internal node has exactly four children: topLefttopRightbottomLeft and bottomRight. Quad trees are often used to partition a two-dimensional space by recursively subdividing it into four quadrants or regions.
We want to store True/False information in our quad tree. The quad tree is used to represent a N * N boolean grid. For each node, it will be subdivided into four children nodes until the values in the region it represents are all the same. Each node has another two boolean attributes : isLeaf and valisLeaf is true if and only if the node is a leaf node. The val attribute for a leaf node contains the value of the region it represents.
For example, below are two quad trees A and B:
A:
+-------+-------+   T: true
|       |       |   F: false
|   T   |   T   |
|       |       |
+-------+-------+
|       |       |
|   F   |   F   |
|       |       |
+-------+-------+
topLeft: T
topRight: T
bottomLeft: F
bottomRight: F

B:               
+-------+---+---+
|       | F | F |
|   T   +---+---+
|       | T | T |
+-------+---+---+
|       |       |
|   T   |   F   |
|       |       |
+-------+-------+
topLeft: T
topRight:
     topLeft: F
     topRight: F
     bottomLeft: T
     bottomRight: T
bottomLeft: T
bottomRight: F

Your task is to implement a function that will take two quadtrees and return a quadtree that represents the logical OR (or union) of the two trees.
A:                 B:                 C (A or B):
+-------+-------+  +-------+---+---+  +-------+-------+
|       |       |  |       | F | F |  |       |       |
|   T   |   T   |  |   T   +---+---+  |   T   |   T   |
|       |       |  |       | T | T |  |       |       |
+-------+-------+  +-------+---+---+  +-------+-------+
|       |       |  |       |       |  |       |       |
|   F   |   F   |  |   T   |   F   |  |   T   |   F   |
|       |       |  |       |       |  |       |       |
+-------+-------+  +-------+-------+  +-------+-------+
Note:
  1. Both A and B represent grids of size N * N.
  2. N is guaranteed to be a power of 2.
  3. If you want to know more about the quad tree, you can refer to its wiki.
  4. The logic OR operation is defined as this: "A or B" is true if A is true, or if B is true, or if both A and B are true.
https://leetcode.com/problems/quad-tree-intersection/discuss/157532/Java-concise-code-beat-100
    public Node intersect(Node q1, Node q2) {
        if (q1.isLeaf) {
            return q1.val ? q1 : q2;
        }
        if (q2.isLeaf) {
            return q2.val ? q2 : q1;
        }
        
        q1.topLeft = intersect(q1.topLeft, q2.topLeft);
        q1.topRight = intersect(q1.topRight, q2.topRight);
        q1.bottomLeft = intersect(q1.bottomLeft, q2.bottomLeft);
        q1.bottomRight = intersect(q1.bottomRight, q2.bottomRight);
        
        if (q1.topLeft.isLeaf && q1.topRight.isLeaf 
            && q1.bottomLeft.isLeaf && q1.bottomRight.isLeaf
            && q1.topLeft.val == q1.topRight.val 
            && q1.topRight.val == q1.bottomLeft.val 
            && q1.bottomLeft.val == q1.bottomRight.val) {
            q1.isLeaf = true;
            q1.val = q1.topLeft.val;
        }
        return q1;
    }

X. https://www.cnblogs.com/lz87/p/9926697.html
24     public Node intersect(Node quadTree1, Node quadTree2) {
25         if(quadTree1 == null || quadTree2 == null) {
26             return null;
27         }
28         if(quadTree1.isLeaf && quadTree2.isLeaf) {
29             return new Node(quadTree1.val || quadTree2.val, true, null, null, null, null);
30         }
31         else if(quadTree1.isLeaf) {
32             return quadTree1.val ? new Node(quadTree1.val, true, null, null, null, null) 
33                 : new Node(quadTree2.val, quadTree2.isLeaf, quadTree2.topLeft, quadTree2.topRight, quadTree2.bottomLeft, quadTree2.bottomRight);
34         }
35         else if(quadTree2.isLeaf) {
36             return quadTree2.val ? new Node(quadTree2.val, true, null, null, null, null) 
37                 : new Node(quadTree1.val, quadTree1.isLeaf, quadTree1.topLeft, quadTree1.topRight, quadTree1.bottomLeft, quadTree1.bottomRight);            
38         }
39         
40         Node topLeft = intersect(quadTree1.topLeft, quadTree2.topLeft);
41         Node topRight = intersect(quadTree1.topRight, quadTree2.topRight);
42         Node bottomLeft = intersect(quadTree1.bottomLeft, quadTree2.bottomLeft);
43         Node bottomRight = intersect(quadTree1.bottomRight, quadTree2.bottomRight);
44         
45         Node root = new Node();
46         if(topLeft.isLeaf && topRight.isLeaf && bottomLeft.isLeaf && bottomRight.isLeaf &&
47            topLeft.val == topRight.val && topRight.val == bottomLeft.val && bottomLeft.val == bottomRight.val) {
48             root.val = topLeft.val;
49             root.isLeaf = true;            
50         }
51         else {
52             root.isLeaf = false;
53             root.topLeft = topLeft;
54             root.topRight = topRight;
55             root.bottomLeft = bottomLeft;
56             root.bottomRight = bottomRight;
57         }
58         return root;
59     }
https://leetcode.com/problems/quad-tree-intersection/discuss/249072/Readable-Java-beats-100
    public Node intersect(Node quadTree1, Node quadTree2) {
        // Terminal condition, when any of two is leaf.
        if (quadTree1.isLeaf) {
            return quadTree1.val ? quadTree1 : quadTree2;
        } else if (quadTree2.isLeaf) {
            return quadTree2.val ? quadTree2 : quadTree1;
        }
        // Recurse in all 4 directions.
        Node tl = intersect(quadTree1.topLeft, quadTree2.topLeft);
        Node tr = intersect(quadTree1.topRight, quadTree2.topRight);
        Node bl = intersect(quadTree1.bottomLeft, quadTree2.bottomLeft);
        Node br = intersect(quadTree1.bottomRight, quadTree2.bottomRight);
        // Detect a merger state when all 4 leaves have same value.
        if (tl.isLeaf && tr.isLeaf && bl.isLeaf && br.isLeaf && tl.val == tr.val && bl.val == br.val && tl.val == bl.val) {
            return new Node(tl.val, true, null, null, null, null);
        } else {
            return new Node(false, false, tl, tr, bl, br);
        }
    }





LeetCode 427 - Construct Quad Tree


https://leetcode.com/problems/construct-quad-tree/
We want to use quad trees to store an N x N boolean grid. Each cell in the grid can only be true or false. The root node represents the whole grid. For each node, it will be subdivided into four children nodes until the values in the region it represents are all the same.
Each node has another two boolean attributes : isLeaf and valisLeaf is true if and only if the node is a leaf node. The val attribute for a leaf node contains the value of the region it represents.
Your task is to use a quad tree to represent a given grid. The following example may help you understand the problem better:
Given the 8 x 8 grid below, we want to construct the corresponding quad tree:
It can be divided according to the definition above:

The corresponding quad tree should be as following, where each node is represented as a (isLeaf, val) pair.
For the non-leaf nodes, val can be arbitrary, so it is represented as *.
Note:
  1. N is less than 1000 and guaranteened to be a power of 2.
  2. If you want to know more about the quad tree, you can refer to its wiki.
X. Post order: O(N)
https://leetcode.com/problems/construct-quad-tree/discuss/154565/Java-recursive-solution
    public Node construct(int[][] grid) {
        return helper(grid, 0, 0, grid.length);
    }
    private Node helper(int[][] grid, int x, int y, int len) {
        if (len == 1) {
            return new Node(grid[x][y] != 0, true, null, null, null, null);
        }
        Node result = new Node();
        Node topLeft = helper(grid, x, y, len / 2);
        Node topRight = helper(grid, x, y + len / 2, len / 2);
        Node bottomLeft = helper(grid, x + len / 2, y, len / 2);
        Node bottomRight = helper(grid, x + len / 2, y + len / 2, len / 2);
        if (topLeft.isLeaf && topRight.isLeaf && bottomLeft.isLeaf && bottomRight.isLeaf
           && topLeft.val == topRight.val && topRight.val == bottomLeft.val && bottomLeft.val == bottomRight.val) {
            result.isLeaf = true;
            result.val = topLeft.val;
        } else {
            result.topLeft = topLeft;
            result.topRight = topRight;
            result.bottomLeft = bottomLeft;
            result.bottomRight = bottomRight;
        }
        return result;
    }
https://leetcode.com/problems/construct-quad-tree/discuss/170983/Easy-to-understand-Java-Recursive-Solution
  1. To do this recusively, we have to split the grid into 4 smaller sub-grids until the sub-grid's length is 1. The sub-grid whose length is 1 is the leaf node.
  2. We merge the sub-grids if all four sub-grids are leaf nodes and have same value.
class Solution {
    public Node construct(int[][] grid) {
        return helper(grid, 0, 0, grid.length);
    }
    private Node helper(int[][] grid, int x, int y, int len) {
        if(len == 1) return new Node(grid[x][y] == 1, true, null, null, null, null);
        
        Node nodeTL = helper(grid, x, y, len/2);
        Node nodeTR = helper(grid, x, y+len/2, len/2);
        Node nodeBL = helper(grid, x+len/2, y, len/2);
        Node nodeBR = helper(grid, x+len/2, y+len/2, len/2);
        // Merge all child nodes
        if(nodeTL.isLeaf && nodeTR.isLeaf && nodeBL.isLeaf && nodeBR.isLeaf) {
            if(nodeTL.val && nodeTR.val && nodeBL.val && nodeBR.val) return new Node(true, true, null, null, null, null);
            if(!nodeTL.val && !nodeTR.val && !nodeBL.val && !nodeBR.val)  return new Node(false, true, null, null, null, null);
        }
        return new Node(true, false, nodeTL, nodeTR, nodeBL, nodeBR);
    }
}
Time Complexity: O(N^2 logN)N is the length of the grid.
Space Complexity: O(N^2)

Why time complexity is O(N^2 logN). Shouldn't it be O(n) , since recursion relation is T(n) = 4*T(n/2) . n is length of the grid.

X.
https://zxi.mytechroad.com/blog/geometry/leetcode-427-construct-quad-tree/
Time complexity: O(n^2*logn)

Space complexity: O(n^2)

http://www.cnblogs.com/grandyang/p/9649348.html
这道题让我们根据一个二维数组来建立一棵四叉树,关于四叉树的介绍题目中也了给了wiki百科的链接。但是博主开始看到题目中给的那个例子,没怎么看懂。后来分析大神们的代码,才略微弄明白了一些。原来叶结点表示的是值相同的一片区域,比如我们看二维数组图示那行的第三个图,首先整个数组被分成了四等份,左上,左下,和右下部分内的值均相同,那么他们都是一个叶结点,而右上只有再四等分一下,才能使各自部分内的值相同,所以其就不是叶结点,而四等分后的每个区间才是叶结点。题目中限定了N的值一定是2的指数,就是说其如果可分的话,一定可以四等分,而之前说了,只有区间内的值不同时,才需要四等分,否则整体就当作一个叶结点。所以我们需要check四等分区间内的值是否相同,当然,我们可以将二维数组拆分为四个二维数组,但是那样可能不太高效,而且还占用额外空间,一个比较好的选择是用坐标变量来控制等分数组的范围,我们只需要一个起始点坐标,和区间的长度,就可以精确定位一个区间了。比如说对于例子中的整个二维数组数组来说,知道起始点坐标 (0, 0),还有长度8,就知道表示的是哪个区间。我们可以遍历这个区间上的其他所有的点,跟起点对比,只要有任何点跟起点不相同,则说明该区间是可分的,因为我们前面说了,只有一个区间上所有的值均相同,才能当作一个叶结点。只要有不同,就表示可以四分,那么我们就新建一个结点,这里的左上,左下,右上,和右下四个子结点就需要用过调用递归函数来实现了,实现原理都一样,重要的地方就是确定每个四分区间的起点和长度,长度好确定,都是当前长度的一半,然后就是把各个区间的起点确定好,这个也不难,就是细心一点,不要写错了就可以了,另外,对于非叶结点,结点值可以是true或者false都没问题。如果某个区间上所有值均相同,那么就生成一个叶结点,结点值就跟区间值相同,isLeaf是true,四个子结点均为NULL即可

    Node* construct(vector<vector<int>>& grid) {
        return build(grid, 0, 0, grid.size());
    }
    Node* build(vector<vector<int>>& grid, int x, int y, int len) {
        if (len <= 0) return NULL;
        for (int i = x; i < x + len; ++i) {
            for (int j = y; j < y + len; ++j) {
                if (grid[i][j] != grid[x][y]) {
                    return new Node(true, false,
                           build(grid, x, y, len / 2),
                           build(grid, x, y + len / 2, len / 2),
                           build(grid, x + len/ 2, y, len / 2),
                           build(grid, x + len / 2, y + len / 2, len / 2));
                }
            }
        }
        return new Node(grid[x][y] == 1, true, NULL, NULL, NULL, NULL);
    }


还有一种写法,记录了区间的左上点和右下点,知道这两个点也可以确定一个区间的位置,整体思路和上面的方法并没有什么太大的区别
    Node* construct(vector<vector<int>>& grid) {
        return build(grid, 0, 0, grid.size() - 1, grid.size() - 1);
    }
    Node* build(vector<vector<int>>& grid, int r1, int c1, int r2, int c2) {
        if (r1 > r2 || c1 > c2) return NULL;
        bool isLeaf = true;
        int val = grid[r1][c1], rowMid = (r1 + r2) / 2, colMid = (c1 + c2) / 2;
        for (int i = r1; i <= r2; ++i) {
            for (int j = c1; j <= c2; ++j) {
                if (grid[i][j] != val) {
                    isLeaf = false;
                    break;
                }
            }
        }
        if (isLeaf) return new Node(val == 1, true, NULL, NULL, NULL, NULL);
        return new Node(false, false, 
               build(grid, r1, c1, rowMid, colMid),
               build(grid, r1, colMid + 1, rowMid, c2),
               build(grid, rowMid + 1, c1, r2, colMid),
               build(grid, rowMid + 1, colMid + 1, r2, c2));
    }
    public Node construct(int[][] g) { return build(0, 0, g.length - 1, g.length - 1, g);}

    Node build(int r1, int c1, int r2, int c2, int[][] g) {
        if (r1 > r2 || c1 > c2) return null;
        boolean isLeaf = true;
        int val = g[r1][c1];
        for (int i = r1; i <= r2; i++)
            for (int j = c1; j <= c2; j++)
                if (g[i][j] != val) {
                    isLeaf = false;
                    break;
                }
        if (isLeaf)
            return new Node(val == 1, true, null, null, null, null);
        int rowMid = (r1 + r2) / 2, colMid = (c1 + c2) / 2;
        return new Node(false, false,
            build(r1, c1, rowMid, colMid, g),//top left 
            build(r1, colMid + 1, rowMid, c2, g),//top right
            build(rowMid + 1, c1, r2, colMid, g),//bottom left 
            build(rowMid + 1, colMid + 1, r2, c2, g));//bottom right
    }

还原黑白图片

给一个只有黑白pixel的图片,调用给定的两个method,把图片重新画出来。两个method分别是:int readSource(int x1, int y1, int x2, int y2)和void writeTarget(int x1, int y1, int x2, int y2);
补充
题目意思大概是要利用第一个method来判断坐标区域内是否为全黑全白或者都有,三种情况会分别返回1,-1,0。第二个method是在坐标区域内画图,但是画出来的图只有黑色。
·LC类似题目:427  construct quad tree

思路:
  1. dfs解法,先检查当前square是否全黑全白,如果全黑,涂黑当前区域,返回,如果全白,返回,如果有黑有白,按照construct quad tree的的思路分成4块递归


https://blog.csdn.net/dpengwang/article/details/84785232
另一道与四分树有关的题
题目 558. Quad Tree Intersection
求两个四分树的OR操作,这道题的解决思想也是递归,不过是两棵树同时递归,每次递归,传入的父节点的位置得是对应的,即他们所表示的区域是相同的。这道题还有要注意的一点是,如果合并以后父节点的子节点的值都是相同的,得将这个父节点转为叶子节点(即删除所有子节点,并把isleaf 设置为True)


Game of Life - hashlife


http://www.thelowlyprogrammer.com/2011/05/game-of-life-part-2-hashlife.html
HashLife is a simple yet interesting algorithm. Invented in 1984 by Bill Gosper (of Gosper glider gun fame), it exploits repeated patterns to dramatically cut down the work required to support large patterns over vast numbers of iterations

At it’s heart, HashLife is built around the concept of a quadtree. If you’re unfamiliar with it, a quadtree takes a square region and breaks it into four quadrants, each a quarter the size of the original. Each quadrant is further broken down into quadrants of its own, and on down. At the bottom, in squares of some minimum size like 2x2, actual points are stored. 
This structure is usually used to make spatial queries like “what points intersect this bounding box” efficient, but in this case two other properties are taken advantage of. First, nodes at any level are uniquely defined by the points within their region, which means duplicated regions can be backed by the same node in memory. For the Game of Life, where there are repeated patterns and empty regions galore, this can drastically reduce the space required. Second, in the Game of Life a square of  (n)x(n) points fully dictates the inner (n-2)x(n-2) core one generation forward, the inner (n/2)x(n/2) core n/4 generations forward, irrespective of what cells are adjacent to it. So the future core of a node can be calculated once and will apply at any future point in time, anywhere in the tree.


Inner nodesTogether these properties allow for ridiculous speedups. Hashing and sharing nodes drastically reduces the space requirements, with exponentially more sharing the further down the tree you go. There are only 16 possible leaf nodes, after all! From this, calculating the future core for a node requires exponentially less time than a naïve implementation would. It can be done by recursively calculating the inner core of smaller nodes, where the better caching comes into play, and then combining them together into a new node. You might be wondering if the gains from caching are lost to the increasing difficulty of determining which nodes are equal, but with a couple careful invariants we actually get that for free. First, nodes must be immutable - this one’s pretty straightforward. Second, nodes must be unique at all times. This forces us to build the tree from the bottom up, but then checking if a new node duplicates an existing one is simply a matter of checking if there are any existing nodes that point to the same set of quadrants in the same order, a problem that hash tables trivially solve.
http://pzemtsov.github.io/2015/04/24/game-of-life-hash-tables-and-hash-codes.html
There are two major classes of Life programs. The matrix-based ones, such as those in my old experiments, store a part of the universe (or the entire universe considered being a toroidal array, as in the examples above) as a matrix. The entire matrix is re-calculated on each step. These programs are very simple but have two disadvantages. Firstly, they are limited by the size of the matrix, and Life structures are known to be able to grow indefinitely (for example, by spawning gliders). This means such programs can only produce approximate results, such as the result we saw for the R-pentamino above. Secondly, most Life colonies contain much fewer live cells than there’re squares in the matrix, which suggests a way of improving speed – to keep track of the occupied cells in some data structure and only process those.

This is the second class of Life programs. Very sophisticated data structures have been used for Life simulation, some with extraordinary performance. For instance, the HashLife approach makes use of identifying repeating patterns both in space and time, with great results.
http://www.drdobbs.com/jvm/an-algorithm-for-compressing-space-and-t/184406478
combines quadtrees and memoization to yield astronomical speedup to the Game of Life
The Game of Life (Figure 1) is a solitaire game played on an infinite two-dimensional grid. Each cell in the grid is either alive (1, denoted by a black circle) or dead. Every living cell that has two or three living neighbors (of the eight immediately adjacent) remains alive, otherwise it dies. Any dead cell surrounded by exactly three living neighbors is a birth cell and is born into the next generation. All the rules are applied to all the cells at the same instant. 

These rules lead to life forms that are stable and oscillate—gliders and spaceships that transport themselves across the universe, life forms that grow without bound or completely die away. Seed patterns with as few as nine initial living cells can mutate for many thousands of generations, with constantly moving areas of chaotic activity spewing forth gliders among a large stable menagerie.

http://pzemtsov.github.io/2015/04/24/game-of-life-hash-tables-and-hash-codes.html
https://discuss.leetcode.com/topic/37410/the-conway-game-of-life-using-hashtable-in-java-fast-solution-which-only-check-alive-cell-and-its-neighbors



Google – Image And


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);
    }
  }
}
Read full article from Google – Image And

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts