Facebook Pixel

427. Construct Quad Tree

Problem Description

This problem asks you to construct a Quad-Tree from a given n × n binary matrix (containing only 0s and 1s).

A Quad-Tree is a tree data structure where each internal node has exactly four children representing the four quadrants: top-left, top-right, bottom-left, and bottom-right. Each node in the tree has two properties:

  • val: A boolean value (True for 1s, False for 0s)
  • isLeaf: A boolean indicating whether the node is a leaf (True) or has four children (False)

The construction follows these rules:

  1. If a region contains all the same values (all 0s or all 1s):

    • Create a leaf node with isLeaf = True
    • Set val to the grid's value (True for 1, False for 0)
    • The four children are set to null
  2. If a region contains mixed values (both 0s and 1s):

    • Create an internal node with isLeaf = False
    • Set val to any value (it doesn't matter since it's not a leaf)
    • Divide the current region into four equal quadrants
    • Recursively construct four children nodes for each quadrant

The solution uses a recursive divide-and-conquer approach. The dfs function takes the boundaries of a rectangular region (a, b) to (c, d) and:

  1. Checks if all values in the region are the same
  2. If yes, creates a leaf node
  3. If no, divides the region into four quadrants and recursively builds child nodes

The key insight is finding the midpoints to split the grid: ((a+c)//2, (b+d)//2) divides the region into four equal parts, and the function recursively processes each quadrant to build the complete Quad-Tree structure.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The natural way to think about this problem is to recognize that a Quad-Tree is inherently a recursive structure - each node either represents a uniform region (leaf) or contains four smaller Quad-Trees as children. This immediately suggests a divide-and-conquer approach.

When we look at any square region in the grid, we face a decision: Is this region uniform (all 0s or all 1s), or does it contain mixed values? If it's uniform, we've found a leaf node and can stop dividing. If it's mixed, we need to break it down further.

The key insight is that we can treat any square sub-region of the grid the same way we treat the entire grid. This recursive property means we can:

  1. Start with the entire grid
  2. Check if it's uniform
  3. If not, split it into four equal quadrants
  4. Apply the same logic to each quadrant

The splitting pattern follows the natural quadrant division: we find the midpoint of our current region and use it to create four smaller squares. For a region from (a, b) to (c, d), the midpoint is ((a+c)//2, (b+d)//2). This gives us:

  • Top-left: from (a, b) to (mid_row, mid_col)
  • Top-right: from (a, mid_col+1) to (mid_row, d)
  • Bottom-left: from (mid_row+1, b) to (c, mid_col)
  • Bottom-right: from (mid_row+1, mid_col+1) to (c, d)

The recursion naturally handles the tree construction: when we determine a region needs to be split, we create a non-leaf node and let the recursive calls build its four children. The base case (uniform region) creates leaf nodes, ensuring the recursion terminates. This bottom-up construction perfectly mirrors the top-down division of the grid, making the solution both elegant and efficient.

Solution Approach

The implementation uses a recursive depth-first search (DFS) approach to construct the Quad-Tree. Here's how the solution works step by step:

Main Function Structure: The construct method initializes the recursive process by calling dfs(0, 0, len(grid) - 1, len(grid[0]) - 1), which processes the entire grid from top-left corner (0, 0) to bottom-right corner (n-1, n-1).

The DFS Helper Function: The dfs(a, b, c, d) function takes four parameters representing a rectangular region:

  • (a, b): top-left corner coordinates
  • (c, d): bottom-right corner coordinates

Step 1: Check Region Uniformity

zero = one = 0
for i in range(a, c + 1):
    for j in range(b, d + 1):
        if grid[i][j] == 0:
            zero = 1
        else:
            one = 1

The function scans the entire region to determine if it contains zeros, ones, or both. Instead of counting all occurrences, it uses binary flags (zero and one) to track presence, which is more efficient.

Step 2: Determine Leaf Status

isLeaf = zero + one == 1
val = isLeaf and one

If zero + one == 1, the region is uniform (contains only 0s or only 1s), making it a leaf node. The val is set to True if the region contains only 1s.

Step 3: Handle Leaf Nodes

if isLeaf:
    return Node(grid[a][b], True)

For uniform regions, create and return a leaf node. Since all values are the same, grid[a][b] represents the entire region's value.

Step 4: Handle Non-Leaf Nodes (Divide and Conquer) For mixed regions, calculate the midpoints and recursively construct four quadrants:

topLeft = dfs(a, b, (a + c) // 2, (b + d) // 2)
topRight = dfs(a, (b + d) // 2 + 1, (a + c) // 2, d)
bottomLeft = dfs((a + c) // 2 + 1, b, c, (b + d) // 2)
bottomRight = dfs((a + c) // 2 + 1, (b + d) // 2 + 1, c, d)

The midpoint calculations (a + c) // 2 and (b + d) // 2 split the region into four equal parts. Each recursive call processes one quadrant and returns its corresponding node.

Step 5: Construct Internal Node

return Node(val, isLeaf, topLeft, topRight, bottomLeft, bottomRight)

Finally, create and return an internal node with the four children obtained from recursive calls. The val for non-leaf nodes can be any value (here it's False from the earlier calculation), and isLeaf is False.

Time Complexity: O(n² log n) in the worst case, where we need to check every cell and the tree has maximum depth. Space Complexity: O(log n) for the recursion stack depth, plus O(n²) for the Quad-Tree nodes in the worst case.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through constructing a Quad-Tree for a 4×4 binary matrix:

grid = [[1,1,0,0],
        [1,1,0,0],
        [1,1,1,1],
        [1,1,1,1]]

Initial Call: dfs(0, 0, 3, 3) - Process entire 4×4 grid

Step 1: Check if the entire grid is uniform

  • Scanning all cells: found both 0s and 1s
  • Not uniform → Need to split into quadrants

Step 2: Calculate midpoints

  • Row midpoint: (0 + 3) // 2 = 1
  • Column midpoint: (0 + 3) // 2 = 1

Step 3: Recursively process four quadrants

Quadrant 1 - Top-Left: dfs(0, 0, 1, 1)

[1,1]
[1,1]
  • All values are 1 → Create leaf node with val=True

Quadrant 2 - Top-Right: dfs(0, 2, 1, 3)

[0,0]
[0,0]
  • All values are 0 → Create leaf node with val=False

Quadrant 3 - Bottom-Left: dfs(2, 0, 3, 1)

[1,1]
[1,1]
  • All values are 1 → Create leaf node with val=True

Quadrant 4 - Bottom-Right: dfs(2, 2, 3, 3)

[1,1]
[1,1]
  • All values are 1 → Create leaf node with val=True

Step 4: Create root node

  • Create internal node with isLeaf=False
  • Attach the four leaf nodes as children

Final Quad-Tree Structure:

        Root (isLeaf=False)
       /    |     |      \
      /     |     |       \
  TL(1)   TR(0)  BL(1)   BR(1)
(leaf)   (leaf) (leaf)   (leaf)

Each leaf represents a 2×2 uniform region, and the root connects them together. The tree efficiently represents the original 4×4 grid with just 5 nodes instead of 16 individual cells.

Solution Implementation

1"""
2# Definition for a QuadTree node.
3class Node:
4    def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight):
5        self.val = val
6        self.isLeaf = isLeaf
7        self.topLeft = topLeft
8        self.topRight = topRight
9        self.bottomLeft = bottomLeft
10        self.bottomRight = bottomRight
11"""
12
13from typing import List, Optional
14
15
16class Solution:
17    def construct(self, grid: List[List[int]]) -> 'Node':
18        """
19        Constructs a QuadTree from a 2D grid of binary values.
20      
21        Args:
22            grid: N x N matrix where N is a power of 2, containing 0s and 1s
23          
24        Returns:
25            Root node of the constructed QuadTree
26        """
27      
28        def build_quadtree(row_start: int, col_start: int, row_end: int, col_end: int) -> 'Node':
29            """
30            Recursively builds a QuadTree for the specified grid region.
31          
32            Args:
33                row_start: Starting row index (inclusive)
34                col_start: Starting column index (inclusive)
35                row_end: Ending row index (inclusive)
36                col_end: Ending column index (inclusive)
37              
38            Returns:
39                Node representing the QuadTree for this region
40            """
41          
42            # Check if all values in the current region are the same
43            has_zero = False
44            has_one = False
45          
46            # Scan through the current region to detect value uniformity
47            for row in range(row_start, row_end + 1):
48                for col in range(col_start, col_end + 1):
49                    if grid[row][col] == 0:
50                        has_zero = True
51                    else:
52                        has_one = True
53                  
54                    # Early exit if we found both values
55                    if has_zero and has_one:
56                        break
57          
58            # Determine if this region is a leaf (all same values)
59            is_leaf = not (has_zero and has_one)  # True if all 0s or all 1s
60          
61            # If leaf node, return with the uniform value
62            if is_leaf:
63                # Value is the actual grid value (0 or 1) at any position in the region
64                node_value = grid[row_start][col_start]
65                return Node(val=node_value, isLeaf=True, 
66                          topLeft=None, topRight=None, 
67                          bottomLeft=None, bottomRight=None)
68          
69            # If not a leaf, divide into four quadrants and recursively build
70            mid_row = (row_start + row_end) // 2
71            mid_col = (col_start + col_end) // 2
72          
73            # Build four quadrants
74            top_left = build_quadtree(row_start, col_start, mid_row, mid_col)
75            top_right = build_quadtree(row_start, mid_col + 1, mid_row, col_end)
76            bottom_left = build_quadtree(mid_row + 1, col_start, row_end, mid_col)
77            bottom_right = build_quadtree(mid_row + 1, mid_col + 1, row_end, col_end)
78          
79            # For non-leaf nodes, val can be any value (typically True or 1)
80            return Node(val=True, isLeaf=False,
81                       topLeft=top_left, topRight=top_right,
82                       bottomLeft=bottom_left, bottomRight=bottom_right)
83      
84        # Start building from the entire grid
85        n = len(grid)
86        return build_quadtree(0, 0, n - 1, n - 1)
87
1/*
2// Definition for a QuadTree node.
3class Node {
4    public boolean val;
5    public boolean isLeaf;
6    public Node topLeft;
7    public Node topRight;
8    public Node bottomLeft;
9    public Node bottomRight;
10
11    public Node() {
12        this.val = false;
13        this.isLeaf = false;
14        this.topLeft = null;
15        this.topRight = null;
16        this.bottomLeft = null;
17        this.bottomRight = null;
18    }
19
20    public Node(boolean val, boolean isLeaf) {
21        this.val = val;
22        this.isLeaf = isLeaf;
23        this.topLeft = null;
24        this.topRight = null;
25        this.bottomLeft = null;
26        this.bottomRight = null;
27    }
28
29    public Node(boolean val, boolean isLeaf, Node topLeft, Node topRight, Node bottomLeft, Node bottomRight) {
30        this.val = val;
31        this.isLeaf = isLeaf;
32        this.topLeft = topLeft;
33        this.topRight = topRight;
34        this.bottomLeft = bottomLeft;
35        this.bottomRight = bottomRight;
36    }
37};
38*/
39
40class Solution {
41    /**
42     * Constructs a QuadTree from a 2D grid
43     * @param grid The input 2D grid containing 0s and 1s
44     * @return The root node of the constructed QuadTree
45     */
46    public Node construct(int[][] grid) {
47        // Start recursive construction from the entire grid
48        return buildQuadTree(0, 0, grid.length - 1, grid[0].length - 1, grid);
49    }
50
51    /**
52     * Recursively builds a QuadTree for a given region of the grid
53     * @param rowStart Starting row index (inclusive)
54     * @param colStart Starting column index (inclusive)
55     * @param rowEnd Ending row index (inclusive)
56     * @param colEnd Ending column index (inclusive)
57     * @param grid The original 2D grid
58     * @return The root node of the QuadTree for this region
59     */
60    private Node buildQuadTree(int rowStart, int colStart, int rowEnd, int colEnd, int[][] grid) {
61        // Check if all values in current region are the same
62        int hasZero = 0;
63        int hasOne = 0;
64      
65        // Scan through the current region to check for 0s and 1s
66        for (int row = rowStart; row <= rowEnd; row++) {
67            for (int col = colStart; col <= colEnd; col++) {
68                if (grid[row][col] == 0) {
69                    hasZero = 1;
70                } else {
71                    hasOne = 1;
72                }
73            }
74        }
75      
76        // If region contains only 0s or only 1s, it's a leaf node
77        boolean isLeaf = (hasZero + hasOne) == 1;
78        // Leaf value is true if region contains only 1s
79        boolean value = isLeaf && (hasOne == 1);
80      
81        // Create the current node
82        Node currentNode = new Node(value, isLeaf);
83      
84        // If it's a leaf node, no need to divide further
85        if (isLeaf) {
86            return currentNode;
87        }
88      
89        // Calculate midpoints for dividing the region into quadrants
90        int midRow = (rowStart + rowEnd) / 2;
91        int midCol = (colStart + colEnd) / 2;
92      
93        // Recursively build four quadrants
94        currentNode.topLeft = buildQuadTree(rowStart, colStart, midRow, midCol, grid);
95        currentNode.topRight = buildQuadTree(rowStart, midCol + 1, midRow, colEnd, grid);
96        currentNode.bottomLeft = buildQuadTree(midRow + 1, colStart, rowEnd, midCol, grid);
97        currentNode.bottomRight = buildQuadTree(midRow + 1, midCol + 1, rowEnd, colEnd, grid);
98      
99        return currentNode;
100    }
101}
102
1/*
2// Definition for a QuadTree node.
3class Node {
4public:
5    bool val;
6    bool isLeaf;
7    Node* topLeft;
8    Node* topRight;
9    Node* bottomLeft;
10    Node* bottomRight;
11
12    Node() {
13        val = false;
14        isLeaf = false;
15        topLeft = NULL;
16        topRight = NULL;
17        bottomLeft = NULL;
18        bottomRight = NULL;
19    }
20
21    Node(bool _val, bool _isLeaf) {
22        val = _val;
23        isLeaf = _isLeaf;
24        topLeft = NULL;
25        topRight = NULL;
26        bottomLeft = NULL;
27        bottomRight = NULL;
28    }
29
30    Node(bool _val, bool _isLeaf, Node* _topLeft, Node* _topRight, Node* _bottomLeft, Node* _bottomRight) {
31        val = _val;
32        isLeaf = _isLeaf;
33        topLeft = _topLeft;
34        topRight = _topRight;
35        bottomLeft = _bottomLeft;
36        bottomRight = _bottomRight;
37    }
38};
39*/
40
41class Solution {
42public:
43    /**
44     * Constructs a QuadTree from a 2D grid
45     * @param grid: 2D integer grid where each cell contains 0 or 1
46     * @return: Root node of the constructed QuadTree
47     */
48    Node* construct(vector<vector<int>>& grid) {
49        int n = grid.size();
50        return buildQuadTree(0, 0, n - 1, n - 1, grid);
51    }
52
53private:
54    /**
55     * Recursively builds a QuadTree for a given region of the grid
56     * @param rowStart: Starting row index (inclusive)
57     * @param colStart: Starting column index (inclusive)
58     * @param rowEnd: Ending row index (inclusive)
59     * @param colEnd: Ending column index (inclusive)
60     * @param grid: Reference to the 2D grid
61     * @return: Node representing the QuadTree for the specified region
62     */
63    Node* buildQuadTree(int rowStart, int colStart, int rowEnd, int colEnd, 
64                        vector<vector<int>>& grid) {
65        // Check if all values in the current region are the same
66        bool hasZero = false;
67        bool hasOne = false;
68      
69        // Scan through the entire region to determine uniformity
70        for (int row = rowStart; row <= rowEnd; ++row) {
71            for (int col = colStart; col <= colEnd; ++col) {
72                if (grid[row][col] == 1) {
73                    hasOne = true;
74                } else {
75                    hasZero = true;
76                }
77              
78                // Early exit if we found both values
79                if (hasZero && hasOne) {
80                    break;
81                }
82            }
83            if (hasZero && hasOne) {
84                break;
85            }
86        }
87      
88        // Determine if this region is a leaf node (all values are the same)
89        bool isLeaf = !(hasZero && hasOne);
90      
91        // For leaf nodes, val is true if all cells are 1, false if all are 0
92        bool nodeValue = isLeaf && hasOne;
93      
94        // Create the current node
95        Node* currentNode = new Node(nodeValue, isLeaf);
96      
97        // If it's a leaf node, no need to subdivide further
98        if (isLeaf) {
99            return currentNode;
100        }
101      
102        // Calculate midpoints for dividing the region into quadrants
103        int rowMid = (rowStart + rowEnd) / 2;
104        int colMid = (colStart + colEnd) / 2;
105      
106        // Recursively build four quadrants
107        currentNode->topLeft = buildQuadTree(rowStart, colStart, rowMid, colMid, grid);
108        currentNode->topRight = buildQuadTree(rowStart, colMid + 1, rowMid, colEnd, grid);
109        currentNode->bottomLeft = buildQuadTree(rowMid + 1, colStart, rowEnd, colMid, grid);
110        currentNode->bottomRight = buildQuadTree(rowMid + 1, colMid + 1, rowEnd, colEnd, grid);
111      
112        return currentNode;
113    }
114};
115
1/**
2 * Definition for a QuadTree node.
3 */
4class Node {
5    val: boolean;
6    isLeaf: boolean;
7    topLeft: Node | null;
8    topRight: Node | null;
9    bottomLeft: Node | null;
10    bottomRight: Node | null;
11
12    constructor(
13        val?: boolean,
14        isLeaf?: boolean,
15        topLeft?: Node | null,
16        topRight?: Node | null,
17        bottomLeft?: Node | null,
18        bottomRight?: Node | null
19    ) {
20        this.val = val === undefined ? false : val;
21        this.isLeaf = isLeaf === undefined ? false : isLeaf;
22        this.topLeft = topLeft === undefined ? null : topLeft;
23        this.topRight = topRight === undefined ? null : topRight;
24        this.bottomLeft = bottomLeft === undefined ? null : bottomLeft;
25        this.bottomRight = bottomRight === undefined ? null : bottomRight;
26    }
27}
28
29/**
30 * Constructs a QuadTree from a 2D grid
31 * @param grid - 2D integer grid where each cell contains 0 or 1
32 * @returns Root node of the constructed QuadTree
33 */
34function construct(grid: number[][]): Node | null {
35    const n = grid.length;
36    return buildQuadTree(0, 0, n - 1, n - 1, grid);
37}
38
39/**
40 * Recursively builds a QuadTree for a given region of the grid
41 * @param rowStart - Starting row index (inclusive)
42 * @param colStart - Starting column index (inclusive)
43 * @param rowEnd - Ending row index (inclusive)
44 * @param colEnd - Ending column index (inclusive)
45 * @param grid - Reference to the 2D grid
46 * @returns Node representing the QuadTree for the specified region
47 */
48function buildQuadTree(
49    rowStart: number,
50    colStart: number,
51    rowEnd: number,
52    colEnd: number,
53    grid: number[][]
54): Node {
55    // Check if all values in the current region are the same
56    let hasZero = false;
57    let hasOne = false;
58  
59    // Scan through the entire region to determine uniformity
60    for (let row = rowStart; row <= rowEnd; row++) {
61        for (let col = colStart; col <= colEnd; col++) {
62            if (grid[row][col] === 1) {
63                hasOne = true;
64            } else {
65                hasZero = true;
66            }
67          
68            // Early exit if we found both values
69            if (hasZero && hasOne) {
70                break;
71            }
72        }
73        if (hasZero && hasOne) {
74            break;
75        }
76    }
77  
78    // Determine if this region is a leaf node (all values are the same)
79    const isLeaf = !(hasZero && hasOne);
80  
81    // For leaf nodes, val is true if all cells are 1, false if all are 0
82    const nodeValue = isLeaf && hasOne;
83  
84    // Create the current node
85    const currentNode = new Node(nodeValue, isLeaf);
86  
87    // If it's a leaf node, no need to subdivide further
88    if (isLeaf) {
89        return currentNode;
90    }
91  
92    // Calculate midpoints for dividing the region into quadrants
93    const rowMid = Math.floor((rowStart + rowEnd) / 2);
94    const colMid = Math.floor((colStart + colEnd) / 2);
95  
96    // Recursively build four quadrants
97    currentNode.topLeft = buildQuadTree(rowStart, colStart, rowMid, colMid, grid);
98    currentNode.topRight = buildQuadTree(rowStart, colMid + 1, rowMid, colEnd, grid);
99    currentNode.bottomLeft = buildQuadTree(rowMid + 1, colStart, rowEnd, colMid, grid);
100    currentNode.bottomRight = buildQuadTree(rowMid + 1, colMid + 1, rowEnd, colEnd, grid);
101  
102    return currentNode;
103}
104

Time and Space Complexity

Time Complexity: O(n² × log n) where n is the side length of the grid.

The analysis breaks down as follows:

  • In the worst case, the quadtree needs to be fully constructed when no regions can be merged into leaves
  • The recursion depth is log n (since we divide the grid into quarters at each level)
  • At each level k of the recursion tree, there are 4^k subproblems
  • Each subproblem at level k processes a grid of size (n/2^k) × (n/2^k) = n²/4^k elements
  • Total work at level k: 4^k × n²/4^k = n²
  • Since there are log n levels, total time complexity is O(n² × log n)

Alternatively, we can view it as:

  • Each cell in the n × n grid can be visited multiple times during the recursion
  • In the worst case, a cell is visited O(log n) times (once at each level of recursion it belongs to)
  • Total: O(n² × log n)

Space Complexity: O(n²)

The space complexity consists of:

  • Recursion stack: O(log n) - The maximum depth of recursion is log n when dividing the grid into quarters
  • QuadTree nodes: O(n²) - In the worst case where no merging is possible, we create O(n²) nodes (approximately (4^(log n) - 1)/3 = (n² - 1)/3 internal nodes plus leaf nodes)
  • The dominant factor is the space for storing the quadtree nodes, giving us O(n²) total space complexity

Common Pitfalls

1. Incorrect Quadrant Boundary Calculation

One of the most common mistakes is incorrectly calculating the boundaries when dividing the region into four quadrants. Developers often make off-by-one errors when determining where each quadrant starts and ends.

Incorrect Example:

# Wrong: Missing +1 for bottom and right quadrants
topLeft = dfs(a, b, (a + c) // 2, (b + d) // 2)
topRight = dfs(a, (b + d) // 2, (a + c) // 2, d)  # Missing +1
bottomLeft = dfs((a + c) // 2, b, c, (b + d) // 2)  # Missing +1
bottomRight = dfs((a + c) // 2, (b + d) // 2, c, d)  # Missing +1 twice

Correct Solution:

mid_row = (row_start + row_end) // 2
mid_col = (col_start + col_end) // 2

topLeft = dfs(row_start, col_start, mid_row, mid_col)
topRight = dfs(row_start, mid_col + 1, mid_row, col_end)
bottomLeft = dfs(mid_row + 1, col_start, row_end, mid_col)
bottomRight = dfs(mid_row + 1, mid_col + 1, row_end, col_end)

2. Confusing Node Value for Non-Leaf Nodes

Many developers mistakenly think they need to calculate a meaningful value for non-leaf nodes, leading to unnecessary complexity.

Incorrect Approach:

if not is_leaf:
    # Unnecessarily complex - trying to determine a "representative" value
    val = grid[(row_start + row_end) // 2][(col_start + col_end) // 2]
    # Or worse, trying to compute majority value
    val = count_ones > count_zeros

Correct Solution: For non-leaf nodes, the val field is irrelevant and can be set to any value (True, False, 0, or 1):

return Node(val=True, isLeaf=False, ...)  # val can be any value

3. Inefficient Region Uniformity Check

Counting all occurrences when you only need to know if the region is uniform wastes time.

Inefficient Example:

# Unnecessarily counting all values
count_zeros = 0
count_ones = 0
for i in range(row_start, row_end + 1):
    for j in range(col_start, col_end + 1):
        if grid[i][j] == 0:
            count_zeros += 1
        else:
            count_ones += 1

is_leaf = (count_zeros == 0) or (count_ones == 0)

Efficient Solution: Use boolean flags and early termination:

has_zero = has_one = False
for row in range(row_start, row_end + 1):
    for col in range(col_start, col_end + 1):
        if grid[row][col] == 0:
            has_zero = True
        else:
            has_one = True
        # Early exit when both values found
        if has_zero and has_one:
            return Node(True, False, ...)  # Not a leaf

4. Incorrect Base Case for Single Cell

Forgetting to handle the base case when the region is a single cell (row_start == row_end and col_start == col_end).

Potential Issue:

# May cause infinite recursion if not handled properly
def dfs(row_start, col_start, row_end, col_end):
    # Missing explicit base case check
    mid_row = (row_start + row_end) // 2  # When equal, this equals row_start
    mid_col = (col_start + col_end) // 2  # When equal, this equals col_start
    # Recursive calls with same parameters → infinite recursion

Solution: The uniformity check naturally handles single cells, but being explicit improves clarity:

# Single cell is always uniform and thus a leaf
if row_start == row_end and col_start == col_end:
    return Node(grid[row_start][col_start], True, None, None, None, None)

5. Misunderstanding Grid Dimensions

Assuming the grid is always square or that N must be a power of 2 in the implementation (though the problem states this, defensive coding is good practice).

Better Practice:

def construct(self, grid: List[List[int]]) -> 'Node':
    if not grid or not grid[0]:
        return None
  
    n = len(grid)
    # Verify square matrix if needed
    assert all(len(row) == n for row in grid), "Grid must be square"
  
    return build_quadtree(0, 0, n - 1, n - 1)
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which data structure is used to implement priority queue?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More