Construct Quad Tree

MediumDivide & Conquer · Recursion on Quadrants🧩 Recursion & Divide and ConquerLeetCode #427 ↗Updated

Problem

You are given an n × n grid of 0s and 1s, where n is a power of two. Encode it as a quad tree: if a square region holds a single value it becomes a leaf (isLeaf = true, val = that value); otherwise it is an internal node whose four children encode its top-left, top-right, bottom-left and bottom-right quarters. Return the root (an internal node's val may be anything).
Input[[0,1],[1,0]]Outputinternal root; leaves TL=0, TR=1, BL=1, BR=0
Input[[1,1],[1,1]]Outputone leaf, val = 1
Input[[1,1,0,0],[1,1,0,0],[0,0,0,1],[0,0,1,1]]Outputroot: TL=leaf 1, TR=leaf 0, BL=leaf 0, BR=internal(0,1,1,1)

n = 2x, 0 ≤ x ≤ 6  ·  grid[i][j] ∈ {0, 1}

Try it yourself

Java
class Solution {
    public Node construct(int[][] grid) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
A region is a leaf exactly when its four quarters are leaves with the same value. Building bottom-up lets each parent decide in O(1) from its children, so no cell is ever re-scanned.
PatternRecursion & Divide and Conquer

Instinct If the answer for n items can be built from the same problem on halves (or smaller pieces) plus a cheap combine step - split, recurse, merge.

Memory hack Split it, trust it, stitch it - nail the base case, take the leap of faith on smaller calls, then glue their answers together.

Open the Recursion & Divide and Conquer guide →

Approaches

Brute ForceTop-Down, Scan Each Region

Time O(n² log n)Space O(log n)

For a square, scan all its cells. If they match, return a leaf; otherwise split into four quarters and recurse. Each of the log n levels can scan up to all n² cells again.

Java
public Node construct(int[][] grid) {
    return build(grid, 0, 0, grid.length);
}
private Node build(int[][] g, int r, int c, int size) {
    if (isUniform(g, r, c, size)) return new Node(g[r][c] == 1, true);
    int h = size / 2;
    return new Node(true, false,
            build(g, r, c, h), build(g, r, c + h, h),
            build(g, r + h, c, h), build(g, r + h, c + h, h));
}
private boolean isUniform(int[][] g, int r, int c, int size) {
    for (int i = r; i < r + size; i++) {
        for (int j = c; j < c + size; j++) {
            if (g[i][j] != g[r][c]) return false;
        }
    }
    return true;
}

Direct translation of the definition; repeated scans add a log factor.

At a glance

LevelApproachTimeSpace
Brute ForceTop-Down, Scan Each RegionO(n² log n)O(log n)
BetterTop-Down with 2D Prefix SumsO(n²)O(n²)
OptimalBottom-Up Merge of QuadrantsO(n²)O(log n)
Common pitfalls
  • Swapping row and column offsets — top-right is (r, c + h), not (r + h, c).
  • Merging four leaves without checking they're all leaves — an internal child can carry any val.
  • Leaving children non-null on leaf nodes — leaves must have all four children null.
Interview tips
  • Clarify the Node fields and child order (TL, TR, BL, BR) before coding.
  • Start top-down with a scan, then mention prefix sums or the bottom-up merge.
  • State the recurrence T(n²) = 4T(n²/4) + O(1) for the bottom-up version.
Pattern
Divide & conquer on quadrants → 2D grids of size 2k that are summarised region by region.
My notes saved in this browser