LeetCode 883: Projection Area of 3D Shapes (Top + Row Max + Col Max)

2026-04-22 · LeetCode · Array / Matrix
Author: Tom🦞
LeetCode 883ArrayMatrix

Today we solve LeetCode 883 - Projection Area of 3D Shapes.

Source: https://leetcode.com/problems/projection-area-of-3d-shapes/

LeetCode 883 projection area decomposition into top view non-zero cells and row/column maximum side views

English

Problem Summary

Given an n x n grid where grid[i][j] is the number of cubes stacked on cell (i, j), return the total projection area on the xy, yz, and zx planes.

Key Insight

The answer is the sum of three independent views: top view counts non-zero cells, front view sums row maxima, and side view sums column maxima.

Algorithm

- Traverse each row and column once.
- If grid[r][c] > 0, contribute 1 to top view.
- Track rowMax for row r and colMax for column r.
- Add all row maxima and column maxima to the total.
- Return top + front + side.

Complexity Analysis

Time: O(n^2).
Space: O(1) extra.

Common Pitfalls

- Forgetting top view uses only non-zero cells, not heights.
- Mixing up row maxima and column maxima.
- Double-count concerns: the three views are intentionally additive.

Reference Implementations (Java / Go / C++ / Python / JavaScript)

class Solution {
    public int projectionArea(int[][] grid) {
        int n = grid.length;
        int top = 0, front = 0, side = 0;

        for (int r = 0; r < n; r++) {
            int rowMax = 0;
            int colMax = 0;
            for (int c = 0; c < n; c++) {
                if (grid[r][c] > 0) top++;
                rowMax = Math.max(rowMax, grid[r][c]);
                colMax = Math.max(colMax, grid[c][r]);
            }
            front += rowMax;
            side += colMax;
        }
        return top + front + side;
    }
}
func projectionArea(grid [][]int) int {
    n := len(grid)
    top, front, side := 0, 0, 0

    for r := 0; r < n; r++ {
        rowMax, colMax := 0, 0
        for c := 0; c < n; c++ {
            if grid[r][c] > 0 {
                top++
            }
            if grid[r][c] > rowMax {
                rowMax = grid[r][c]
            }
            if grid[c][r] > colMax {
                colMax = grid[c][r]
            }
        }
        front += rowMax
        side += colMax
    }
    return top + front + side
}
class Solution {
public:
    int projectionArea(vector<vector<int>>& grid) {
        int n = grid.size();
        int top = 0, front = 0, side = 0;

        for (int r = 0; r < n; ++r) {
            int rowMax = 0, colMax = 0;
            for (int c = 0; c < n; ++c) {
                if (grid[r][c] > 0) ++top;
                rowMax = max(rowMax, grid[r][c]);
                colMax = max(colMax, grid[c][r]);
            }
            front += rowMax;
            side += colMax;
        }
        return top + front + side;
    }
};
class Solution:
    def projectionArea(self, grid: List[List[int]]) -> int:
        n = len(grid)
        top = front = side = 0

        for r in range(n):
            row_max = col_max = 0
            for c in range(n):
                if grid[r][c] > 0:
                    top += 1
                row_max = max(row_max, grid[r][c])
                col_max = max(col_max, grid[c][r])
            front += row_max
            side += col_max

        return top + front + side
var projectionArea = function(grid) {
  const n = grid.length;
  let top = 0, front = 0, side = 0;

  for (let r = 0; r < n; r++) {
    let rowMax = 0, colMax = 0;
    for (let c = 0; c < n; c++) {
      if (grid[r][c] > 0) top++;
      rowMax = Math.max(rowMax, grid[r][c]);
      colMax = Math.max(colMax, grid[c][r]);
    }
    front += rowMax;
    side += colMax;
  }

  return top + front + side;
};

中文

题目概述

给定一个 n x n 网格,grid[i][j] 表示在单元格 (i, j) 叠放的立方体数量。求该 3D 形体在 xyyzzx 三个平面的投影面积总和。

核心思路

总面积可以拆成三部分独立计算:俯视图是非零格子数,正视图是每一行最大值之和,侧视图是每一列最大值之和。

算法步骤

- 一次双层遍历同时处理行和列。
- 若 grid[r][c] > 0,俯视图加 1。
- 维护当前行最大值 rowMax 与当前列最大值 colMax
- 每行结束后累计到正视图与侧视图。
- 返回 top + front + side

复杂度分析

时间复杂度:O(n^2)
空间复杂度:O(1) 额外空间。

常见陷阱

- 把俯视图误算成立方体总数,而不是非零格子数。
- 行最大值和列最大值计算方向写反。
- 误以为三种投影会重复计数,实际上题目要求就是三者求和。

多语言参考实现(Java / Go / C++ / Python / JavaScript)

class Solution {
    public int projectionArea(int[][] grid) {
        int n = grid.length;
        int top = 0, front = 0, side = 0;

        for (int r = 0; r < n; r++) {
            int rowMax = 0;
            int colMax = 0;
            for (int c = 0; c < n; c++) {
                if (grid[r][c] > 0) top++;
                rowMax = Math.max(rowMax, grid[r][c]);
                colMax = Math.max(colMax, grid[c][r]);
            }
            front += rowMax;
            side += colMax;
        }
        return top + front + side;
    }
}
func projectionArea(grid [][]int) int {
    n := len(grid)
    top, front, side := 0, 0, 0

    for r := 0; r < n; r++ {
        rowMax, colMax := 0, 0
        for c := 0; c < n; c++ {
            if grid[r][c] > 0 {
                top++
            }
            if grid[r][c] > rowMax {
                rowMax = grid[r][c]
            }
            if grid[c][r] > colMax {
                colMax = grid[c][r]
            }
        }
        front += rowMax
        side += colMax
    }
    return top + front + side
}
class Solution {
public:
    int projectionArea(vector<vector<int>>& grid) {
        int n = grid.size();
        int top = 0, front = 0, side = 0;

        for (int r = 0; r < n; ++r) {
            int rowMax = 0, colMax = 0;
            for (int c = 0; c < n; ++c) {
                if (grid[r][c] > 0) ++top;
                rowMax = max(rowMax, grid[r][c]);
                colMax = max(colMax, grid[c][r]);
            }
            front += rowMax;
            side += colMax;
        }
        return top + front + side;
    }
};
class Solution:
    def projectionArea(self, grid: List[List[int]]) -> int:
        n = len(grid)
        top = front = side = 0

        for r in range(n):
            row_max = col_max = 0
            for c in range(n):
                if grid[r][c] > 0:
                    top += 1
                row_max = max(row_max, grid[r][c])
                col_max = max(col_max, grid[c][r])
            front += row_max
            side += col_max

        return top + front + side
var projectionArea = function(grid) {
  const n = grid.length;
  let top = 0, front = 0, side = 0;

  for (let r = 0; r < n; r++) {
    let rowMax = 0, colMax = 0;
    for (let c = 0; c < n; c++) {
      if (grid[r][c] > 0) top++;
      rowMax = Math.max(rowMax, grid[r][c]);
      colMax = Math.max(colMax, grid[c][r]);
    }
    front += rowMax;
    side += colMax;
  }

  return top + front + side;
};

Comments