Skip to content

LeetCode 883: Projection Area of 3D Shapes

A clear explanation of computing the projection areas of stacked cubes from top, front, and side views.

Problem Restatement

We are given an n x n grid.

Each cell:

grid[r][c]

contains a vertical stack of cubes.

We want the total projection area of the 3D shape onto three planes:

ProjectionMeaning
Top viewLooking down from above
Front viewLooking from the front
Side viewLooking from the side

Return the sum of these three projection areas. The official problem defines each cube as a 1 x 1 x 1 cube aligned to the axes. (leetcode.com)

Input and Output

ItemMeaning
Inputgrid, an n x n matrix
OutputTotal projection area
Cell valueNumber of stacked cubes
Cube size1 x 1 x 1

Function shape:

def projectionArea(self, grid: list[list[int]]) -> int:
    ...

Examples

Example 1:

Input: grid = [[1,2],[3,4]]
Output: 17

Top projection:

Every nonzero cell contributes 1.

There are 4 nonzero cells:

top = 4

Front projection uses the largest value in each row:

RowMaximum
[1,2]2
[3,4]4
front = 2 + 4 = 6

Side projection uses the largest value in each column:

ColumnMaximum
[1,3]3
[2,4]4
side = 3 + 4 = 7

Total:

4 + 6 + 7 = 17

Example 2:

Input: grid = [[2]]
Output: 5

Top projection:

1

Front projection:

2

Side projection:

2

Total:

1 + 2 + 2 = 5

First Thought: Simulate Every Cube

We could imagine building the entire 3D structure cube by cube.

Then for each viewing direction, determine which cubes are visible.

This works conceptually, but it is unnecessary.

The projections follow simple patterns that can be computed directly from the grid values.

Key Insight

Each projection can be computed independently.

Top Projection

Looking from above, a cell contributes area 1 if it contains at least one cube.

So the top projection equals:

number of nonzero cells

Front Projection

Looking from the front, each row contributes the height of its tallest stack.

So the front projection equals:

sum of row maximums

Side Projection

Looking from the side, each column contributes the height of its tallest stack.

So the side projection equals:

sum of column maximums

The total answer is:

top + front + side

Algorithm

Initialize:

answer = 0

For each row:

  1. Count nonzero cells for the top projection.
  2. Add the row maximum for the front projection.

For each column:

  1. Add the column maximum for the side projection.

Return the total.

Walkthrough

Use:

grid = [
    [1, 2],
    [3, 4]
]

Top Projection

Every nonzero cell contributes 1.

CellContributes
1Yes
2Yes
3Yes
4Yes

Total:

4

Front Projection

Take the maximum of each row:

RowMax
[1,2]2
[3,4]4

Total:

6

Side Projection

Take the maximum of each column:

ColumnMax
[1,3]3
[2,4]4

Total:

7

Final answer:

4 + 6 + 7 = 17

Correctness

The top projection shows whether at least one cube exists in each grid position. A stack of height 1 and a stack of height 100 both cover exactly one square in the top view. Therefore, every nonzero cell contributes exactly 1 area to the top projection.

The front projection looks across each row. In a row, shorter stacks are hidden behind the tallest stack. Therefore, the visible height contributed by a row is exactly the maximum value in that row. Summing row maximums gives the full front projection area.

The side projection works similarly for columns. In each column, only the tallest stack determines the visible height from the side. Therefore, summing column maximums gives the side projection area.

The three projections are independent and non-overlapping measurements. Adding them together gives the total projection area required by the problem.

Thus, the algorithm computes the correct total projection area.

Complexity

Let:

n = len(grid)
MetricValueWhy
TimeO(n^2)We scan all cells
SpaceO(1)Only a few counters are used

Implementation

class Solution:
    def projectionArea(self, grid: list[list[int]]) -> int:
        n = len(grid)

        top = 0
        front = 0
        side = 0

        for row in grid:
            front += max(row)

            for value in row:
                if value > 0:
                    top += 1

        for col in range(n):
            column_max = 0

            for row in range(n):
                column_max = max(column_max, grid[row][col])

            side += column_max

        return top + front + side

Code Explanation

We track the three projection areas separately:

top = 0
front = 0
side = 0

For each row:

for row in grid:

the front projection gains the tallest stack:

front += max(row)

Every nonzero cell contributes to the top projection:

if value > 0:
    top += 1

Then we process columns:

for col in range(n):

We find the tallest stack in each column:

column_max = max(column_max, grid[row][col])

and add it to the side projection:

side += column_max

Finally, return the sum of all three projections:

return top + front + side

Testing

def run_tests():
    s = Solution()

    assert s.projectionArea([[1, 2], [3, 4]]) == 17
    assert s.projectionArea([[2]]) == 5
    assert s.projectionArea([[1, 0], [0, 2]]) == 8
    assert s.projectionArea([[0]]) == 0
    assert s.projectionArea([[1, 1, 1]]) == 5
    assert s.projectionArea([[1], [2], [3]]) == 10

    print("all tests passed")

run_tests()

Test meaning:

TestWhy
[[1,2],[3,4]]Standard example
[[2]]Single stack
Sparse nonzero cellsChecks top projection logic
[[0]]Empty shape
Single rowFront projection dominates
Single columnSide projection dominates