You are given an n x n
grid grid
where grid[i][j]
represents the height of a stack of cubes located at cell (i, j)
. Imagine placing stacks of cubes on a 2D grid, where each stack’s height is given by the value in the grid. Your task is to compute the total area of the projections of these cubes onto the three principal planes:
Return the sum of the areas of these three projections.
Constraints:
n == grid.length == grid[i].length
1 <= n <= 50
0 <= grid[i][j] <= 50
The problem asks for the sum of three projection areas. Let's break down what each projection means:
grid[i][j] > 0
) contributes 1 to the area.
A brute-force approach would be to scan the grid multiple times: once for the top view, once for each row (front), and once for each column (side). However, we can optimize by collecting all these values in a single pass through the grid.
The key insight is that we can compute all three projections efficiently by iterating through the grid once, keeping track of the required maxima for rows and columns as we go.
Let's outline the steps to solve this problem efficiently:
top
for the top view areafront_max
as a list to keep track of the maximum value in each row (front view)side_max
as a list to keep track of the maximum value in each column (side view)grid[i][j]
:
grid[i][j] > 0
, increment top
front_max[i]
if grid[i][j]
is greater than the current valueside_max[j]
if grid[i][j]
is greater than the current valuetop + sum(front_max) + sum(side_max)
This approach ensures we only traverse the grid once, collecting all necessary information efficiently.
Let's use the following example input:
grid = [ [1, 2], [3, 4] ]
Step-by-step:
At each iteration, we update the row and column maxima and count nonzero cells for the top view.
class Solution:
def projectionArea(self, grid):
n = len(grid)
top = 0
front = 0
side = 0
for i in range(n):
row_max = 0
col_max = 0
for j in range(n):
if grid[i][j] > 0:
top += 1
row_max = max(row_max, grid[i][j])
col_max = max(col_max, grid[j][i])
front += row_max
side += col_max
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 i = 0; i < n; ++i) {
int row_max = 0, col_max = 0;
for (int j = 0; j < n; ++j) {
if (grid[i][j] > 0) top++;
row_max = max(row_max, grid[i][j]);
col_max = max(col_max, grid[j][i]);
}
front += row_max;
side += col_max;
}
return top + front + side;
}
};
class Solution {
public int projectionArea(int[][] grid) {
int n = grid.length;
int top = 0, front = 0, side = 0;
for (int i = 0; i < n; i++) {
int rowMax = 0, colMax = 0;
for (int j = 0; j < n; j++) {
if (grid[i][j] > 0) top++;
rowMax = Math.max(rowMax, grid[i][j]);
colMax = Math.max(colMax, grid[j][i]);
}
front += rowMax;
side += colMax;
}
return top + front + side;
}
}
var projectionArea = function(grid) {
let n = grid.length;
let top = 0, front = 0, side = 0;
for (let i = 0; i < n; i++) {
let rowMax = 0, colMax = 0;
for (let j = 0; j < n; j++) {
if (grid[i][j] > 0) top++;
rowMax = Math.max(rowMax, grid[i][j]);
colMax = Math.max(colMax, grid[j][i]);
}
front += rowMax;
side += colMax;
}
return top + front + side;
};
Since n ≤ 50, this solution is efficient and well within constraints.
The Projection Area of 3D Shapes problem is elegantly solved by recognizing that each projection corresponds to simple properties of the grid: nonzero cells, row maxima, and column maxima. By iterating through the grid once and updating these values on the fly, we obtain an efficient and clear solution. The key insight is to treat each projection as a separate area calculation and combine them at the end.