三维形体投影面积

标签: 几何 数组 数学 矩阵

难度: Easy

 n x n 的网格 grid 中,我们放置了一些与 x,y,z 三轴对齐的 1 x 1 x 1 立方体。

每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上。

现在,我们查看这些立方体在 xy 、yz 和 zx 平面上的投影

投影 就像影子,将 三维 形体映射到一个 二维 平面上。从顶部、前面和侧面看立方体时,我们会看到“影子”。

返回 所有三个投影的总面积

示例 1:

输入:[[1,2],[3,4]]
输出:17
解释:这里有该形体在三个轴对齐平面上的三个投影(“阴影部分”)。

示例 2:

输入:grid = [[2]]
输出:5

示例 3:

输入:[[1,0],[0,2]]
输出:8

提示:

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

Submission

运行时间: 23 ms

内存: 16.1 MB

class Solution:
    def projectionArea(self, grid: List[List[int]]) -> int:
        xyArea = sum(v > 0 for row in grid for v in row)
        yzArea = sum(map(max, zip(*grid)))  # 注意这里为 O(n) 空间复杂度,改为下标枚举则可以 O(1)
        zxArea = sum(map(max, grid))
        return xyArea + yzArea + zxArea

Explain

本题需要计算三维形体在三个不同的平面上的投影面积。投影面积的计算方法如下: 1. **xy平面投影面积**:所有非零正方体的个数,即每个格子上的正方体数如果大于0,则该格子在xy平面上有投影。 2. **yz平面投影面积**:对每一列,取最大值,这是因为在y轴方向看过去,每列的最高点决定了该列的投影高度。 3. **zx平面投影面积**:对每一行,取最大值,这是因为在x轴方向看过去,每行的最高点决定了该行的投影宽度。 最后,将这三个投影面积相加得到总投影面积。

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

空间复杂度: O(n)

class Solution:
    def projectionArea(self, grid: List[List[int]]) -> int:
        # 计算xy平面的投影面积,即网格中非零元素的数量
        xyArea = sum(v > 0 for row in grid for v in row)
        # 计算yz平面的投影面积,即每一列的最大值之和
        yzArea = sum(map(max, zip(*grid)))  # 使用zip(*grid)来转置矩阵,然后计算每一行(原矩阵的每一列)的最大值
        # 计算zx平面的投影面积,即每一行的最大值之和
        zxArea = sum(map(max, grid))
        # 返回三个投影面积的总和
        return xyArea + yzArea + zxArea

Explore

在计算yz平面的投影面积时,选择每列的最大值是因为我们需要考虑在y轴方向看向形体时能看到的'最高'的部分。由于形体在此方向的视觉高度由各列的最高点决定,因此每列的最大值正是这种视觉高度的直接体现。使用列的平均值或求和不符合实际的投影原理,因为这些统计量并不能正确表示在特定视角下能看到的形体的轮廓。

在计算xy平面的投影面积时,我使用了列表推导式来迭代grid中的每一行,进而迭代每行中的每个元素。通过条件判断 'v > 0' 确保仅计算非零元素的数量。具体代码是 'sum(v > 0 for row in grid for v in row)',这里,'v > 0' 对每个元素进行判断,如果为真,则计数器增加,最终通过sum函数计算出总的非零元素数量。

使用zip(*grid)进行矩阵转置是Python中的一种便利方法,但它并不总是内存效率高。在处理大规模数据时,zip函数创建一个元组的迭代器,其中每个元组包含转置后矩阵的一行。这意味着所有行数据都会被加载到内存中,可能导致大量内存使用。对于非常大的数据集,这可能导致效率低下或内存不足的问题。在这种情况下,可能需要考虑其他更内存高效的矩阵操作方法或使用专门的数值计算库如NumPy,它提供了更高效的数据结构和操作方法。

在代码实现中,应当考虑边界情况,如空的grid会导致所有投影面积为零。对于非常不规则的grid(例如,某些行或列比其他行或列长),代码仍然能够正确执行,因为Python的max函数和迭代器处理可以适应不同长度的迭代。在处理空grid时,由于使用sum和max,空集合(如空行或空列)会返回0,这确保了即使在边界情况下也能得到正确的计算结果。