news 2026/9/12 5:17:36

LeetCode-Go 题解 892:三维形体的表面积(Surface Area of 3D Shapes)—— 网格叠放立方体的表面积求解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode-Go 题解 892:三维形体的表面积(Surface Area of 3D Shapes)—— 网格叠放立方体的表面积求解

LeetCode-Go 题解 892:三维形体的表面积(Surface Area of 3D Shapes)—— 网格叠放立方体的表面积求解

【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go

本篇技术指南围绕 LeetCode 892 题「Surface Area of 3D Shapes(三维形体的表面积)」展开,以 LeetCode-Go 仓库中 leetcode/0892.Surface-Area-of-3D-Shapes/README.md 为骨架,结合仓库内 完整 Go 实现 与 单元测试,讲解「先求独立柱体表面积、再扣除相邻重叠面」的经典解法,并给出逐行代码讲解、复杂度分析与可复现的测试验证方式。读完本文,你将掌握这类网格堆叠类几何题的通用解题套路,并能直接运行仓库代码验证结果。

题目描述

在一个N * N的网格上,我们放置一些1 * 1 * 1的立方体。

每个值v = grid[i][j]表示在网格单元格(i, j)上叠放了v个立方体(形成一个竖直柱体)。

请返回最终得到的立体图形的总表面积

官方给出的五个示例:

示例输入 grid输出
Example 1[[2]]10
Example 2[[1,2],[3,4]]34
Example 3[[1,0],[0,2]]16
Example 4[[1,1,1],[1,0,1],[1,1,1]]32
Example 5[[2,2,2],[2,1,2],[2,2,2]]46

约束条件(Note)

  • 1 <= N <= 50
  • 0 <= grid[i][j] <= 50

即网格边长最大为 50,单个柱体最高可叠 50 个立方体,且允许grid[i][j] = 0(该单元格不放置任何立方体)。

题目大意

用一句话概括:给定一个N * N的二维数组,数组中的每个值v = grid[i][j]表示在该单元格上叠放v1 * 1 * 1的小立方体(竖直堆叠成一个柱体),求这些叠放立方体最终组成的三维形体的外表面面积之和。

需要特别注意的是:本题求的是所有暴露在外的表面,内部被相邻柱体遮挡的面、以及柱体之间相互贴合的接触面都不能计入。

解题思路:独立柱体求和 + 重叠面扣除

核心思想

这是 LeetCode-Go 仓库题解中定位为简单题的一类问题。整体思路非常直观,分两步走:

  1. 先假设所有柱体彼此独立:每个单元格(i, j)上叠放v个立方体,形成一个高为v的竖直柱体,其表面积为4 * v + 2(四个侧面共4 * v个面,加上顶部 1 个面、底部 1 个面)。
  2. 再扣除重叠的面:当相邻的两个柱体彼此接触时,接触部位的面会被遮挡,需要从总面积中减去。每对相邻柱体在接触方向上被遮挡的面数为2 * min(v1, v2)(两个柱体各有一侧的面被遮住,各为min(v1, v2)个)。

按题目意思,找到叠放时重叠的面,然后用总表面积减去这些重叠的面积,即为最终答案。

重叠面为什么要减两次

这是整个解法的关键细节。假设单元格(i, j)v1,其右侧邻居(i, j+1)v2,且v1 < v2

  • (i, j)柱体看,面向右侧的v1个面全部被邻居遮挡;
  • (i, j+1)柱体看,面向左侧的v1个面也全部被(i, j)柱体遮挡。

所以这一对邻居之间,实际被隐藏的面是2 * min(v1, v2)。在代码实现中,每个单元格只对自己的上、下、左、右四个方向各减一次min(自身高度, 邻居高度),由于每条邻接边会被左右(或上下)两个端点各处理一次,恰好实现了"减两次",与几何事实完全吻合。

边缘与空单元格处理

  • grid[i][j] == 0时直接跳过:该位置没有立方体,既没有表面积贡献,也不参与重叠面计算(min(0, x) = 0本身也不会产生扣除,跳过只是省去无意义的计算)。
  • 对网格边界处的单元格,只需检查存在的邻居方向(如i > 0才检查上方,i < len(grid)-1才检查下方),避免数组越界。

Go 实现与逐行讲解

仓库中的完整实现位于 leetcode/0892.Surface-Area-of-3D-Shapes/892. Surface Area of 3D Shapes.go,代码与 README 题解完全一致:

package leetcode func surfaceArea(grid [][]int) int { area := 0 for i := 0; i < len(grid); i++ { for j := 0; j < len(grid[0]); j++ { if grid[i][j] == 0 { continue } area += grid[i][j]*4 + 2 // up if i > 0 { m := min(grid[i][j], grid[i-1][j]) area -= m } // down if i < len(grid)-1 { m := min(grid[i][j], grid[i+1][j]) area -= m } // left if j > 0 { m := min(grid[i][j], grid[i][j-1]) area -= m } // right if j < len(grid[i])-1 { m := min(grid[i][j], grid[i][j+1]) area -= m } } } return area } func min(a, b int) int { if a > b { return b } return a }

逐段拆解如下:

  1. 初始化area := 0累积最终表面积。
  2. 双重遍历:外层i遍历行、内层j遍历列,覆盖N * N全部单元格。
  3. 跳过空单元格if grid[i][j] == 0 { continue },高度为 0 的单元格不参与计算。
  4. 累加独立柱体表面积area += grid[i][j]*4 + 2。一个高v的柱体有4 * v个侧面(每层立方体贡献 4 个侧面)加上顶部和底部各 1 个面。
  5. 扣除四个方向的重叠面
    • 上方:min(grid[i][j], grid[i-1][j]),当i > 0时执行;
    • 下方:min(grid[i][j], grid[i+1][j]),当i < len(grid)-1时执行;
    • 左方:min(grid[i][j], grid[i][j-1]),当j > 0时执行;
    • 右方:min(grid[i][j], grid[i][j+1]),当j < len(grid[i])-1时执行。
  6. 辅助函数min:返回两数中的较小者,即两柱体在接触方向上的重叠层数。

用手算验证示例

以 Example 1[[2]]为例:只有一个高度为 2 的柱体,area = 2*4 + 2 = 10,没有邻居可扣除,最终返回10,与预期一致。

以 Example 2[[1,2],[3,4]]为例:

  • 四个柱体独立表面积:6 + 10 + 14 + 18 = 48
  • 四条邻接边(横向两条、纵向两条)的重叠量分别为min(1,2)=1min(3,4)=3min(1,3)=1min(2,4)=2,共扣除2 * (1+3+1+2) = 14
  • 最终48 - 14 = 34,与官方输出一致。

以 Example 3[[1,0],[0,2]]为例:两个柱体独立表面积为6 + 10 = 16,所有邻接边中至少有一端高度为 0,min值均为 0,无需扣除,最终16与预期一致。这也验证了零值单元格不会引入任何额外扣除。

复杂度分析

  • 时间复杂度O(N²)。算法对N * N个单元格各遍历一次,每个单元格最多进行 4 次常数时间的min比较。
  • 空间复杂度O(1)。只使用了一个整型变量area累积结果,不随输入规模增长。

在题目约束N <= 50下,最多只有 2500 个单元格,无论时间还是空间都非常充裕。

测试验证:覆盖全部官方示例

仓库为本题提供了完整的单元测试文件 leetcode/0892.Surface-Area-of-3D-Shapes/892. Surface Area of 3D Shapes_test.go。测试采用「参数 + 期望答案」的结构化组织方式:定义para892(输入二维数组one)与ans892(期望输出one),再将二者组合成question892用例列表,最后在Test_Problem892中逐一断言。

测试用例完整覆盖了 README 中的五个官方示例:

输入期望输出
[[2]]10
[[1,2],[3,4]]34
[[1,0],[0,2]]16
[[1,1,1],[1,0,1],[1,1,1]]32
[[2,2,2],[2,1,2],[2,2,2]]46

这五个用例恰好覆盖了各种关键场景:单柱体(Example 1)、满高度矩阵(Example 2、5)、含零值单元格(Example 3)、含凹陷空洞的环状结构(Example 4),能够有效验证重叠面扣除逻辑的正确性。

在仓库根目录执行以下命令即可运行本题测试:

go test -v -run Test_Problem892 "./leetcode/0892.Surface-Area-of-3D-Shapes/"

测试运行时会打印每个用例的输入与surfaceArea的计算输出,例如:

【input】:[[2]] 【output】:10 【input】:[[1 2] [3 4]] 【output】:34 【input】:[[1 0] [0 2]] 【output】:16 【input】:[[1 1 1] [1 0 1] [1 1 1]] 【output】:32 【input】:[[2 2 2] [2 1 2] [2 2 2]] 【output】:46

若需验证整个仓库的测试与覆盖率,可参考根目录 gotest.sh 中的脚本方式,一次性对全部题解运行带覆盖率统计的测试:

go test -covermode=atomic -coverprofile=coverage.txt ./leetcode/...

仓库要求所有题解具备 100% 的测试覆盖率,本题的测试用例正是这一工程规范的体现。仓库使用的 Go 版本为go 1.19(见 go.mod),上述命令可直接在项目根目录下执行。

小结

本题的核心结论可以归纳为一条公式:

总表面积 = Σ(每个非零柱体的 4*v + 2) − 2 * Σ(所有相邻柱体的 min(v1, v2))

其中"每个相邻柱体对只计算一次重叠、但扣除时按两侧各一次"是避免重复与遗漏的关键。相比把每个立方体的 6 个面逐一数出来的暴力做法,这种"整体求和、局部扣除"的思路把问题从三维降维到二维邻接关系上,代码简洁且不易出错,也是 LeetCode-Go 仓库对该题给出的标准解法。理解本题后,类似的「网格堆叠 / 相邻贡献扣除」类题目(如岛屿周长、柱状图相关几何题)都可以复用同一套分析框架。

【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 5:17:24

CTF实战:从Web漏洞到隐写分析,系统梳理获取FLAG的常见方法

1. 内容整体设计与思路拆解1.1 FLAG 为什么是 CTF 的“终极目标”CTF&#xff08;Capture The Flag&#xff0c;夺旗赛&#xff09;的核心玩法很简单——题目里藏着一个字符串&#xff0c;叫 FLAG&#xff0c;你把它找出来、提交上去&#xff0c;就能得分。比赛排名看的就是谁能…

作者头像 李华
网站建设 2026/9/12 5:15:27

GPT Image 2实战指南:从多模态原理到提示词工程的资源合集

GPT Image 2发布以后&#xff0c;身边不少做设计、运营、内容创作的朋友都在问同一个问题&#xff1a;这个模型到底能干什么&#xff0c;和之前的版本比有什么不同&#xff0c;怎么才能真正把它用起来而不是只会生成几张好看的图&#xff1f;我搜集整理了一段时间的资料&#x…

作者头像 李华
网站建设 2026/9/12 5:13:06

SpringBoot整合MyBatis时@Mapper注解失效的解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 5:11:11

毕业论文降重与润色全攻略:从人工修改到AI工具的进阶之路

1. 引言&#xff1a;论文修改的痛点与挑战 作为一名正在赶毕业论文的大学生&#xff0c;我深知在最后几周里&#xff0c;如何高效地修改和提升论文质量是多么重要。尤其是在盲审提交前&#xff0c;选择合适的文本修改方式&#xff0c;既能提高效率&#xff0c;也能降低因文本问…

作者头像 李华