Easy
题目描述
在一个 n x n 的网格 grid 中,我们放置了一些与 x,y,z 三轴对齐的 1 x 1 x 1 的正方体。
每个值 v = grid[i][j] 表示 v 个正方体叠放在对应格子 (i, j) 上。
现在,我们查看这些正方体在 xy 、yz 和 zx 平面上的投影。
投影 就像影子,将我们的 3 维图形映射到一个 2 维平面上。从顶部、前面和侧面看立方体时,我们会看到"影子"。
返回 所有三个投影的总面积 。
示例 1:
输入:grid = [[1,2],[3,4]]
输出:17
解释:这里有该形体在三个轴对齐平面上的三个投影("阴影部分")。
示例 2:
输入:grid = [[2]]
输出:5
示例 3:
输入:grid = [[1,0],[0,2]]
输出:8
提示:
n == grid.length == grid[i].length1 <= n <= 500 <= grid[i][j] <= 50
解题思路
这道题需要计算3D形体在三个平面上的投影面积。关键是理解每个投影的几何意义:
xy平面投影(俯视图):从上往下看,只要某个位置有立方体(grid[i][j] > 0),该位置就会在投影中占据一个单位面积。
yz平面投影(侧视图):从侧面看,每一行的投影面积等于该行中的最大高度,因为最高的立方体会"遮挡"其他立方体。
zx平面投影(正视图):从正面看,每一列的投影面积等于该列中的最大高度。
算法步骤:
- 遍历整个网格,统计xy平面投影面积(非零格子数)
- 计算每行的最大值之和,得到yz平面投影面积
- 计算每列的最大值之和,得到zx平面投影面积
- 返回三个投影面积的总和
时间复杂度为O(n²),空间复杂度为O(1)。
代码实现
class Solution {
public:
int projectionArea(vector<vector<int>>& grid) {
int n = grid.size();
int xy = 0, yz = 0, zx = 0;
for (int i = 0; i < n; i++) {
int maxRow = 0, maxCol = 0;
for (int j = 0; j < n; j++) {
// xy投影:非零格子
if (grid[i][j] > 0) xy++;
// yz投影:每行最大值
maxRow = max(maxRow, grid[i][j]);
// zx投影:每列最大值
maxCol = max(maxCol, grid[j][i]);
}
yz += maxRow;
zx += maxCol;
}
return xy + yz + zx;
}
};
class Solution:
def projectionArea(self, grid: List[List[int]]) -> int:
n = len(grid)
xy = yz = zx = 0
for i in range(n):
max_row = max_col = 0
for j in range(n):
# xy投影:非零格子
if grid[i][j] > 0:
xy += 1
# yz投影:每行最大值
max_row = max(max_row, grid[i][j])
# zx投影:每列最大值
max_col = max(max_col, grid[j][i])
yz += max_row
zx += max_col
return xy + yz + zx
public class Solution {
public int ProjectionArea(int[][] grid) {
int n = grid.Length;
int xy = 0, yz = 0, zx = 0;
for (int i = 0; i < n; i++) {
int maxRow = 0, maxCol = 0;
for (int j = 0; j < n; j++) {
// xy投影:非零格子
if (grid[i][j] > 0) xy++;
// yz投影:每行最大值
maxRow = Math.Max(maxRow, grid[i][j]);
// zx投影:每列最大值
maxCol = Math.Max(maxCol, grid[j][i]);
}
yz += maxRow;
zx += maxCol;
}
return xy + yz + zx;
}
}
var projectionArea = function(grid) {
const n = grid.length;
let xy = 0, yz = 0, zx = 0;
for (let i = 0; i < n; i++) {
let maxRow = 0, maxCol = 0;
for (let j = 0; j < n; j++) {
// xy投影:非零格子
if (grid[i][j] > 0) xy++;
// yz投影:每行最大值
maxRow = Math.max(maxRow, grid[i][j]);
// zx投影:每列最大值
maxCol = Math.max(maxCol, grid[j][i]);
}
yz += maxRow;
zx += maxCol;
}
return xy + yz + zx;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n²) | 需要遍历整个 n×n 的网格 |
| 空间复杂度 | O(1) | 只使用常数个额外变量 |