Build a QuadTree From a Grid
Company: Uber
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of spatial data structures and recursive divide-and-conquer techniques by compressing uniform regions into a QuadTree representation.
Constraints
- 1 <= n <= 64
- n is a power of two
- Each row of `grid` has length `n`
- Values support equality comparison
Examples
Input: ([[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]],)
Expected Output: {'value': None, 'isLeaf': False, 'topLeft': {'value': 1, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'topRight': {'value': 2, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'bottomLeft': {'value': 3, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'bottomRight': {'value': 4, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}}
Explanation: Each 2 x 2 quadrant is uniform, so the root is an internal node with four leaf children holding values 1, 2, 3, and 4.
Input: ([[7, 7], [7, 7]],)
Expected Output: {'value': 7, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}
Explanation: The entire grid has the same value, so it compresses into a single leaf node.
Input: ([[-5]],)
Expected Output: {'value': -5, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}
Explanation: A single cell is always a uniform region, so the result is one leaf node.
Input: ([[1, 1, 2, 3], [1, 1, 2, 3], [4, 4, 5, 5], [4, 4, 5, 6]],)
Expected Output: {'value': None, 'isLeaf': False, 'topLeft': {'value': 1, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'topRight': {'value': None, 'isLeaf': False, 'topLeft': {'value': 2, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'topRight': {'value': 3, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'bottomLeft': {'value': 2, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'bottomRight': {'value': 3, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}}, 'bottomLeft': {'value': 4, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'bottomRight': {'value': None, 'isLeaf': False, 'topLeft': {'value': 5, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'topRight': {'value': 5, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'bottomLeft': {'value': 5, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}, 'bottomRight': {'value': 6, 'isLeaf': True, 'topLeft': None, 'topRight': None, 'bottomLeft': None, 'bottomRight': None}}}
Explanation: The top-left and bottom-left quadrants are uniform, but the top-right and bottom-right quadrants each require one more level of splitting.
Hints
- Use divide-and-conquer recursion on square sub-regions of the grid.
- Before splitting a region, scan it to check whether all cells are equal; as soon as you find a different value, you can stop and split.