Construct Quad Tree
MEDIUMDescription
Given a n * n matrix grid of 0's and 1's only. We want to represent grid with a Quad-Tree.
Return the root of the Quad-Tree representing grid.
A Quad-Tree is a tree data structure in which each internal node has exactly four children. Besides, each node has two attributes:
val: True if the node represents a grid of 1's or False if the node represents a grid of 0's. Notice that you can assign thevalto True or False whenisLeafis False, and both are accepted in the answer.isLeaf: True if the node is a leaf node on the tree or False if the node has four children.
class Node {
public boolean val;
public boolean isLeaf;
public Node topLeft;
public Node topRight;
public Node bottomLeft;
public Node bottomRight;
}
We can construct a Quad-Tree from a two-dimensional area using the following steps:
- If the current grid has the same value (i.e all
1'sor all0's) setisLeafTrue and setvalto the value of the grid and set the four children to Null and stop. - If the current grid has different values, set
isLeafto False and setvalto any value and divide the current grid into four sub-grids as shown in the photo. - Recurse for each of the children with the proper sub-grid.
If you want to know more about the Quad-Tree, you can refer to the wiki.
Quad-Tree format:
You don't need to read this section for solving the problem. This is only if you want to understand the output format here. The output represents the serialized format of a Quad-Tree using level order traversal, where null signifies a path terminator where no node exists below.
It is very similar to the serialization of the binary tree. The only difference is that the node is represented as a list [isLeaf, val].
If the value of isLeaf or val is True we represent it as 1 in the list [isLeaf, val] and if the value of isLeaf or val is False we represent it as 0.
Example 1:
Input: grid = [[0,1],[1,0]] Output: [[0,1],[1,0],[1,1],[1,1],[1,0]] Explanation: The explanation of this example is shown below: Notice that 0 represents False and 1 represents True in the photo representing the Quad-Tree.![]()
Example 2:

Input: grid = [[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0]] Output: [[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]] Explanation: All values in the grid are not the same. We divide the grid into four sub-grids. The topLeft, bottomLeft and bottomRight each has the same value. The topRight have different values so we divide it into 4 sub-grids where each has the same value. Explanation is shown in the photo below:![]()
Constraints:
n == grid.length == grid[i].lengthn == 2xwhere0 <= x <= 6
Approaches
Checkout 3 different approaches to solve Construct Quad Tree. Click on different approaches to view the approach and algorithm in detail.
Naive Recursive Approach
This approach directly implements the recursive definition of the Quad Tree construction. A helper function is defined that takes the coordinates and size of the current sub-grid. This function first checks if all values in the sub-grid are the same. If they are, it creates a leaf node. If not, it creates an internal node, divides the grid into four equal quadrants, and makes a recursive call for each quadrant to build the sub-trees.
Algorithm
- Create a recursive helper function
build(grid, row, col, size). - In the helper function, check if the sub-grid from
(row, col)ofsize x sizeis homogeneous. - To check for homogeneity, iterate through all
size * sizecells and compare them to the first cell's value. - If the sub-grid is homogeneous, create and return a leaf node with
isLeaf=trueandvalset to the common value. - If the sub-grid is not homogeneous, create an internal node with
isLeaf=false. - Recursively call
buildfor the four quadrants:topLeft = build(grid, row, col, size/2)topRight = build(grid, row, col + size/2, size/2)bottomLeft = build(grid, row + size/2, col, size/2)bottomRight = build(grid, row + size/2, col + size/2, size/2)
- Assign the results to the children of the internal node and return it.
- The initial call is
construct(grid)which callsbuild(grid, 0, 0, grid.length).
The core of this method is a recursive function, let's call it build(row, col, size). This function is responsible for constructing the Quad Tree for the size x size sub-grid starting at (row, col).
The process within build(row, col, size) is as follows:
- Homogeneity Check: First, we determine if the sub-grid is homogeneous (contains all 0s or all 1s). We can do this by taking the value of the top-left cell,
grid[row][col], and then iterating through all the cells in thesize x sizesub-grid. If we find any cell with a different value, the grid is not homogeneous. - Leaf Node Creation: If the check passes (the grid is homogeneous), we create a new
Node. We setisLeaftotrue,valto the common value (true for 1, false for 0), and all four children pointers tonull. This node is then returned. - Internal Node Creation: If the check fails (the grid has mixed values), we create an internal node. We set
isLeaftofalseandvalto an arbitrary value (e.g.,true). Then, we divide the currentsize x sizegrid into four(size/2) x (size/2)sub-grids and make recursive calls tobuildfor each of these four sub-grids, assigning the returned nodes to thetopLeft,topRight,bottomLeft, andbottomRightchildren of the current internal node. This node is then returned.
The initial call to start the process would be build(0, 0, n), where n is the dimension of the input grid.
class Solution {
public Node construct(int[][] grid) {
return build(grid, 0, 0, grid.length);
}
private Node build(int[][] grid, int row, int col, int size) {
// Check if the sub-grid is homogeneous
boolean isHomogeneous = true;
int firstVal = grid[row][col];
for (int i = row; i < row + size; i++) {
for (int j = col; j < col + size; j++) {
if (grid[i][j] != firstVal) {
isHomogeneous = false;
break;
}
}
if (!isHomogeneous) {
break;
}
}
if (isHomogeneous) {
return new Node(firstVal == 1, true, null, null, null, null);
} else {
int newSize = size / 2;
Node topLeft = build(grid, row, col, newSize);
Node topRight = build(grid, row, col + newSize, newSize);
Node bottomLeft = build(grid, row + newSize, col, newSize);
Node bottomRight = build(grid, row + newSize, col + newSize, newSize);
// The 'val' for an internal node can be arbitrary, e.g., true.
return new Node(true, false, topLeft, topRight, bottomLeft, bottomRight);
}
}
}
Complexity Analysis
Pros and Cons
- Simple to understand and implement as it directly follows the problem definition.
- Does not require any extra data structures for pre-computation.
- Inefficient due to redundant computations. The homogeneity check for a sub-grid re-scans cells that were already scanned by its parent's check.
Code Solutions
Checking out 3 solutions in different languages for Construct Quad Tree. Click on different languages to view the code.
/* // Definition for a QuadTree node. class Node { public boolean val; public boolean isLeaf; public Node topLeft; public Node topRight; public Node bottomLeft; public Node bottomRight; public Node() { this.val = false; this.isLeaf = false; this.topLeft = null; this.topRight = null; this.bottomLeft = null; this.bottomRight = null; } public Node(boolean val, boolean isLeaf) { this.val = val; this.isLeaf = isLeaf; this.topLeft = null; this.topRight = null; this.bottomLeft = null; this.bottomRight = null; } public Node(boolean val, boolean isLeaf, Node topLeft, Node topRight, Node bottomLeft, Node bottomRight) { this.val = val; this.isLeaf = isLeaf; this.topLeft = topLeft; this.topRight = topRight; this.bottomLeft = bottomLeft; this.bottomRight = bottomRight; } }; */ class Solution { public Node construct ( int [][] grid ) { return dfs ( 0 , 0 , grid . length - 1 , grid [ 0 ]. length - 1 , grid ); } private Node dfs ( int a , int b , int c , int d , int [][] grid ) { int zero = 0 , one = 0 ; for ( int i = a ; i <= c ; ++ i ) { for ( int j = b ; j <= d ; ++ j ) { if ( grid [ i ][ j ] == 0 ) { zero = 1 ; } else { one = 1 ; } } } boolean isLeaf = zero + one == 1 ; boolean val = isLeaf && one == 1 ; Node node = new Node ( val , isLeaf ); if ( isLeaf ) { return node ; } node . topLeft = dfs ( a , b , ( a + c ) / 2 , ( b + d ) / 2 , grid ); node . topRight = dfs ( a , ( b + d ) / 2 + 1 , ( a + c ) / 2 , d , grid ); node . bottomLeft = dfs (( a + c ) / 2 + 1 , b , c , ( b + d ) / 2 , grid ); node . bottomRight = dfs (( a + c ) / 2 + 1 , ( b + d ) / 2 + 1 , c , d , grid ); return node ; } }Video Solution
Watch the video walkthrough for Construct Quad Tree
Similar Questions
5 related questions you might find useful
Algorithms:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.