三维形体的表面积

标签: 几何 数组 数学 矩阵

难度: Easy

给你一个 n * n 的网格 grid ,上面放置着一些 1 x 1 x 1 的正方体。每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。

放置好正方体后,任何直接相邻的正方体都会互相粘在一起,形成一些不规则的三维形体。

请你返回最终这些形体的总表面积。

注意:每个形体的底面也需要计入表面积中。

示例 1:

输入:grid = [[1,2],[3,4]]
输出:34

示例 2:

输入:grid = [[1,1,1],[1,0,1],[1,1,1]]
输出:32

示例 3:

输入:grid = [[2,2,2],[2,1,2],[2,2,2]]
输出:46

提示:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 50
  • 0 <= grid[i][j] <= 50

Submission

运行时间: 38 ms

内存: 16.0 MB

class Solution:
    def surfaceArea(self, grid: List[List[int]]) -> int:
        # 派一个小人横向走一遍+纵向走一遍,上下台阶求费力值,
        # 数组大于零的个数*2即为上下底面积
        a = 0   # 计算大于零的数即上下底面积
        ans = 0 # 计算侧面积
        n = len(grid)   # 数组的横竖个数
        for i in range(n):
            row = 0
            lie = 0
            for j in range(n):
                if grid[i][j] > 0:
                    a += 1      # 大于零说明地面有方格+1
                # 走台阶费力值就是上一次台阶和本次台阶的差值
                ans = ans + abs(row - grid[i][j]) + abs(lie - grid[j][i])
                lie = grid[j][i]
                row = grid[i][j]
            ans = ans + lie + row
        return (ans+a*2)    # 上下底面加侧面



Explain

此题解首先遍历网格中的每个单元格,计算每个单元格上正方体的底面和顶面总面积。如果一个单元格中的正方体数量大于0,则它有底面和顶面,因此为每个正方体增加2的面积。对于侧面积,考虑每个单元格在横向和纵向与其相邻单元格之间的正方体数量差值。通过计算这些差值的绝对值,可以得到正方体间未被相邻正方体覆盖的侧面面积。遍历完成后,将底面和顶面的总面积与侧面面积加和,得到最终的结果。

时间复杂度: O(n^2)

空间复杂度: O(1)

class Solution:
    def surfaceArea(self, grid: List[List[int]]) -> int:
        a = 0   # 存储正方体的顶面和底面总面积
        ans = 0 # 存储所有侧面的总面积
        n = len(grid)   # 网格的大小
        for i in range(n):
            row = 0
            lie = 0
            for j in range(n):
                if grid[i][j] > 0:
                    a += 1      # 计算具有顶面和底面的正方体数量
                # 计算当前正方体与横向和纵向相邻正方体的高度差
                ans = ans + abs(row - grid[i][j]) + abs(lie - grid[j][i])
                lie = grid[j][i]
                row = grid[i][j]
            # 在每一行和每一列结束时加上最后一个正方体的高度,因为最外侧的正方体也有侧面
            ans = ans + lie + row
        return (ans + a * 2)    # 计算总表面积,包括侧面和顶面底面

Explore

在三维空间中,每个正方体都有其独立的顶面和底面,与其他正方体是否相邻无关。因此,每个单元格中的正方体数量直接决定了顶面和底面的数量。例如,如果一个单元格中有三个正方体堆叠,那么它们共同形成一个底面(在最下面的正方体)和一个顶面(在最上面的正方体)。这两个面的面积不受其他正方体的影响,所以必须独立计算。

侧面面积取决于正方体堆叠的高度与其相邻单元格的高度之间的差异。如果一个单元格的正方体比相邻单元格的正方体高,那么这种高度差就形成了侧面露出,这部分侧面没有被相邻的正方体覆盖。因此,计算侧面面积时,需要考虑每个单元格与其相邻单元格在高度上的差值。这种计算方法确保了所有未被覆盖的侧面面积都被准确计算。

是的,题解中确实考虑了网格边界的情况。在每一行和每一列的计算中,起始的单元格被假设与一个高度为0的虚拟单元格相邻,这意味着每行和每列的第一个单元格的侧面会完全计算在内。同理,每行和每列的最后一个单元格也相邻一个高度为0的虚拟单元格,因此其侧面也会被完全计算。这样的处理确保了网格的边界正方体的侧面也被正确地计入总面积。

这样做的目的是确保在每一行或每一列的最后一个单元格的正方体的侧面被计算。由于每一行和每一列的末尾正方体在该方向上没有相邻的单元格,所以需要将这些正方体的高度直接加到侧面面积中。这保证了所有外围正方体的侧面都能正确地被计入总表面积,避免因为边界位置而遗漏任何侧面面积。