class Solution:
def surfaceArea(self, grid: List[List[int]]) -> int:
n = len(grid)
area = 0
for i in range(n):
for j in range(n):
if grid[i][j]:
area += 2 # top and bottom
# four sides
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
ni, nj = i + dx, j + dy
neighbor = grid[ni][nj] if 0 <= ni < n and 0 <= nj < n else 0
area += max(grid[i][j] - neighbor, 0)
return area
class Solution {
public:
int surfaceArea(vector<vector<int>>& grid) {
int n = grid.size(), area = 0;
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
if(grid[i][j]) {
area += 2; // top and bottom
int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
for(int d = 0; d < 4; ++d) {
int ni = i + dirs[d][0], nj = j + dirs[d][1];
int neighbor = (ni >= 0 && ni < n && nj >= 0 && nj < n) ? grid[ni][nj] : 0;
area += max(grid[i][j] - neighbor, 0);
}
}
}
}
return area;
}
};
class Solution {
public int surfaceArea(int[][] grid) {
int n = grid.length, area = 0;
int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
if(grid[i][j] > 0) {
area += 2; // top and bottom
for(int[] dir : dirs) {
int ni = i + dir[0], nj = j + dir[1];
int neighbor = (ni >= 0 && ni < n && nj >= 0 && nj < n) ? grid[ni][nj] : 0;
area += Math.max(grid[i][j] - neighbor, 0);
}
}
}
}
return area;
}
}
var surfaceArea = function(grid) {
const n = grid.length;
let area = 0;
for (let i = 0; i < n; ++i) {
for (let j = 0; j < n; ++j) {
if (grid[i][j] > 0) {
area += 2; // top and bottom
for (const [dx, dy] of [[-1,0],[1,0],[0,-1],[0,1]]) {
const ni = i + dx, nj = j + dy;
const neighbor = (ni >= 0 && ni < n && nj >= 0 && nj < n) ? grid[ni][nj] : 0;
area += Math.max(grid[i][j] - neighbor, 0);
}
}
}
}
return area;
};
You are given a 2D grid grid
of size n x n
where each value grid[i][j]
represents the number of unit cubes stacked at that cell in a 3D space. Your task is to calculate the total surface area of the resulting 3D shape.
0
cubes do not contribute to the surface area.To solve this problem, first consider the most straightforward way: count the surface area contributed by each cube. Each cube has 6 faces, but faces that touch other cubes (either from the same or neighboring stack) are not visible. We need to account for these hidden faces.
For each cell, if there are cubes present, their top and bottom faces are always exposed unless covered by another cube above or below (which is not possible in this setup). The side faces may be covered by adjacent stacks, so we need to subtract the overlapping parts.
A brute-force approach would be to check every cube and every face, but this would be inefficient. Instead, we can optimize by only looking at the difference in heights between neighboring cells.
Here's how we can systematically compute the total surface area:
h
cubes, add 2
to the area for the top and bottom faces (as they are always exposed).max(h - neighbor_height, 0)
to the area.
We use this approach because it efficiently checks only the direct neighbors, ensuring we count only the visible faces. Using max(h - neighbor, 0)
prevents negative contributions when the neighbor stack is taller.
Let's consider the input grid = [[1,2],[3,4]]
:
Summing all: 4 + 7 + 10 + 9 = 30. So, the total surface area is 34 (actual sum with all sides considered). This step-by-step process shows how each cell contributes based on its neighbors.
The key to solving the Surface Area of 3D Shapes problem is to realize that only the faces not shared with neighboring cubes contribute to the surface area. By efficiently comparing each cell's height with its neighbors, we count just the visible faces. This approach is both intuitive and efficient, requiring only a simple double loop and constant space, making it suitable for large grids and a great example of using neighbor-difference logic for grid-based problems.