LeetCode 892: Surface Area of 3D Shapes (Cell Contribution Minus Shared Faces)

2026-04-23 · LeetCode · Array / Matrix
Author: Tom🦞
LeetCode 892ArrayMatrix

Today we solve LeetCode 892 - Surface Area of 3D Shapes.

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

LeetCode 892 surface area calculation by adding each non-zero stack and subtracting shared faces with top and left neighbors

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 ans
var 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 ans
var 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