三维形体的表面积
题目
在 N * N
的网格上,我们放置一些 1 * 1 * 1
的立方体。
每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。
请你返回最终形体的表面积。
示例 1:
输入:[[2]]
输出:10
示例 2:
输入:[[1,2],[3,4]]
输出:34
示例 3:
输入:[[1,0],[0,2]]
输出:16
示例 4:
输入:[[1,1,1],[1,0,1],[1,1,1]]
输出:32
示例 5:
输入:[[2,2,2],[2,1,2],[2,2,2]]
输出:46
解题思路
思路:做减法
首先,理解题意。题目要求的在 N * N 的网格中,放置立方体。
先看看题目所给的示例 1 中输入的内容
输入:[[2]]
输出:10
这里表示,在 1 * 1 的网格中,垂直放置 2 个正方体。
再看示例 2:
输入:[[1,2],[3,4]]
输出:34
这里可能这样直接看,不太看得出来什么意思,稍微变动一下:
[
[1, 2],
[3, 4]
]
这里就表示在 2 * 2 的表格中,在对应的单元格中,分别放置 1, 2, 3, 4 个立方体。
理解完题意之后,要考虑堆放立方的时候,可能会出现重叠的部分。只要出现重叠的情况,就要减去 2 个单位。如下图所示:
可以将重叠的情况分为上图所示的三种:
- 垂直重叠
- 相对行重叠
- 相对列重叠
对于垂直重叠这种情况:
比较好计算,只要当前单元格的立方体的数量大于 1,那么就会有重叠的部分,重叠部分的数量就是立方体数量减 1。
对于相对行重叠:
因为单元格的立方体有可能大于 1 的情况,从行的角度出发,立方体可能会有高低之分(若是文字比较难理解,可以考虑画图,将立方体重叠的部分投影到二维平面上)。可以得到这个时候从行的角度来看,重叠的部分就是相邻两个单元格的值的最小值
对于相对列重叠:
这个情况跟上面"相对行重叠"的情况是类似的,从列的角度来看,重叠的部分就是相邻两个单元格的值的最小值。
将重叠的情况罗列出来之后,就可以在遍历的时候计算这三种情况,上面有提及,只要有重叠的部分,那么就会减去 2 个单位。所以需要计算的有两部分:
- 堆放的所有立方体的表面积;
- 每个重叠部分数量消耗 2 个单位的表面积。
具体实现如下面的代码。
代码实现
class Solution:
def surfaceArea(self, grid: List[List[int]]) -> int:
# 题目给出的是 N * N,这里默认行列都是 N
length = len(grid)
cube = 0
# 三个重叠的情况
vertical_overlap = 0
row_overlap = 0
col_overlap = 0
for i in range(length):
for j in range(length):
# 计算立方体的个数
cube += grid[i][j]
# 考虑垂直重叠的情况
if grid[i][j] > 1:
vertical_overlap += (grid[i][j] - 1)
# 考虑相对行重叠的情况
if j > 0:
row_overlap += min(grid[i][j-1], grid[i][j])
# 考虑相对列重叠的情况
if i > 0:
col_overlap += min(grid[i-1][j], grid[i][j])
return cube * 6 - (vertical_overlap + row_overlap + col_overlap ) * 2
实现结果
以上就是针对《三维形体的表面积》问题,根据做减法的思路,先罗列可能的重叠的情况,然后在做最后计算的时候减去重叠部分消耗的单位面积进而求得最终解。