LeetCode 892: Surface Area of 3D Shapes (Cell Contribution Minus Shared Faces)
LeetCode 892ArrayMatrixToday we solve LeetCode 892 - Surface Area of 3D Shapes.
Source: https://leetcode.com/problems/surface-area-of-3d-shapes/
English
Problem Summary
Given an n x n grid where grid[i][j] is the stack height of unit cubes at cell (i, j), compute the total outer surface area of the 3D shape.
Key Insight
For a stack of height h > 0, isolated contribution is 4h + 2 (four sides plus top and bottom). Adjacent stacks share faces, so each shared pair removes 2 * min(h1, h2) from total.
Algorithm
- Traverse each cell once.
- If height h = 0, skip.
- Add 4h + 2 to answer.
- Subtract 2 * min(h, topNeighbor) when row > 0.
- Subtract 2 * min(h, leftNeighbor) when col > 0.
- Return the accumulated surface area.
Complexity Analysis
Time: O(n^2).
Space: O(1) extra.
Common Pitfalls
- Forgetting top and bottom faces for non-zero stacks.
- Subtracting neighbor overlap twice (only check top and left to avoid duplicate deduction).
- Not using min(h1, h2) for shared face count.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int surfaceArea(int[][] grid) {
int n = grid.length;
int ans = 0;
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++) {
int h = grid[r][c];
if (h == 0) continue;
ans += 4 * h + 2;
if (r > 0) ans -= 2 * Math.min(h, grid[r - 1][c]);
if (c > 0) ans -= 2 * Math.min(h, grid[r][c - 1]);
}
}
return ans;
}
}func surfaceArea(grid [][]int) int {
n := len(grid)
ans := 0
for r := 0; r < n; r++ {
for c := 0; c < n; c++ {
h := grid[r][c]
if h == 0 {
continue
}
ans += 4*h + 2
if r > 0 {
ans -= 2 * min(h, grid[r-1][c])
}
if c > 0 {
ans -= 2 * min(h, grid[r][c-1])
}
}
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}class Solution {
public:
int surfaceArea(vector<vector<int>>& grid) {
int n = grid.size();
int ans = 0;
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
int h = grid[r][c];
if (h == 0) continue;
ans += 4 * h + 2;
if (r > 0) ans -= 2 * min(h, grid[r - 1][c]);
if (c > 0) ans -= 2 * min(h, grid[r][c - 1]);
}
}
return ans;
}
};class Solution:
def surfaceArea(self, grid: List[List[int]]) -> int:
n = len(grid)
ans = 0
for r in range(n):
for c in range(n):
h = grid[r][c]
if h == 0:
continue
ans += 4 * h + 2
if r > 0:
ans -= 2 * min(h, grid[r - 1][c])
if c > 0:
ans -= 2 * min(h, grid[r][c - 1])
return ansvar surfaceArea = function(grid) {
const n = grid.length;
let ans = 0;
for (let r = 0; r < n; r++) {
for (let c = 0; c < n; c++) {
const h = grid[r][c];
if (h === 0) continue;
ans += 4 * h + 2;
if (r > 0) ans -= 2 * Math.min(h, grid[r - 1][c]);
if (c > 0) ans -= 2 * Math.min(h, grid[r][c - 1]);
}
}
return ans;
};中文
题目概述
给定一个 n x n 网格,grid[i][j] 表示单元格 (i, j) 上堆叠的单位立方体高度。求该 3D 形体的总外表面积。
核心思路
每个高度为 h > 0 的柱子,单独看贡献 4h + 2。相邻柱子之间会贴合,重叠面需要扣除,且每对重叠要减去 2 * min(h1, h2)。
算法步骤
- 遍历每个格子。
- 若 h = 0,跳过。
- 累加该柱子的基础贡献 4h + 2。
- 若上方存在格子,减去与上方的贴合面积 2 * min(h, up)。
- 若左侧存在格子,减去与左侧的贴合面积 2 * min(h, left)。
- 最终得到总表面积。
复杂度分析
时间复杂度:O(n^2)。
空间复杂度:O(1) 额外空间。
常见陷阱
- 漏掉非零柱子的顶面和底面。
- 同一组相邻关系重复扣减(只看上和左即可)。
- 重叠面计算没有使用 min(h1, h2)。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int surfaceArea(int[][] grid) {
int n = grid.length;
int ans = 0;
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++) {
int h = grid[r][c];
if (h == 0) continue;
ans += 4 * h + 2;
if (r > 0) ans -= 2 * Math.min(h, grid[r - 1][c]);
if (c > 0) ans -= 2 * Math.min(h, grid[r][c - 1]);
}
}
return ans;
}
}func surfaceArea(grid [][]int) int {
n := len(grid)
ans := 0
for r := 0; r < n; r++ {
for c := 0; c < n; c++ {
h := grid[r][c]
if h == 0 {
continue
}
ans += 4*h + 2
if r > 0 {
ans -= 2 * min(h, grid[r-1][c])
}
if c > 0 {
ans -= 2 * min(h, grid[r][c-1])
}
}
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}class Solution {
public:
int surfaceArea(vector<vector<int>>& grid) {
int n = grid.size();
int ans = 0;
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
int h = grid[r][c];
if (h == 0) continue;
ans += 4 * h + 2;
if (r > 0) ans -= 2 * min(h, grid[r - 1][c]);
if (c > 0) ans -= 2 * min(h, grid[r][c - 1]);
}
}
return ans;
}
};class Solution:
def surfaceArea(self, grid: List[List[int]]) -> int:
n = len(grid)
ans = 0
for r in range(n):
for c in range(n):
h = grid[r][c]
if h == 0:
continue
ans += 4 * h + 2
if r > 0:
ans -= 2 * min(h, grid[r - 1][c])
if c > 0:
ans -= 2 * min(h, grid[r][c - 1])
return ansvar surfaceArea = function(grid) {
const n = grid.length;
let ans = 0;
for (let r = 0; r < n; r++) {
for (let c = 0; c < n; c++) {
const h = grid[r][c];
if (h === 0) continue;
ans += 4 * h + 2;
if (r > 0) ans -= 2 * Math.min(h, grid[r - 1][c]);
if (c > 0) ans -= 2 * Math.min(h, grid[r][c - 1]);
}
}
return ans;
};
Comments