题目描述
在 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
解法
方法一:数学
我们可以分别计算三个投影的面积。
- xy 平面的投影面积:每个非零值都会投影到 xy 平面,所以 xy 的投影面积为非零值的个数。
- yz 平面的投影面积:每一行的最大值。
- zx 平面的投影面积:每一列的最大值。
最后将三个面积相加即可。
时间复杂度 $O(n^2)$,其中 $n$ 为网格 grid
的边长。空间复杂度 $O(1)$。
| class Solution:
def projectionArea(self, grid: List[List[int]]) -> int:
xy = sum(v > 0 for row in grid for v in row)
yz = sum(max(row) for row in grid)
zx = sum(max(col) for col in zip(*grid))
return xy + yz + zx
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | class Solution {
public int projectionArea(int[][] grid) {
int xy = 0, yz = 0, zx = 0;
for (int i = 0, n = grid.length; i < n; ++i) {
int maxYz = 0;
int maxZx = 0;
for (int j = 0; j < n; ++j) {
if (grid[i][j] > 0) {
++xy;
}
maxYz = Math.max(maxYz, grid[i][j]);
maxZx = Math.max(maxZx, grid[j][i]);
}
yz += maxYz;
zx += maxZx;
}
return xy + yz + zx;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution {
public:
int projectionArea(vector<vector<int>>& grid) {
int xy = 0, yz = 0, zx = 0;
for (int i = 0, n = grid.size(); i < n; ++i) {
int maxYz = 0, maxZx = 0;
for (int j = 0; j < n; ++j) {
xy += grid[i][j] > 0;
maxYz = max(maxYz, grid[i][j]);
maxZx = max(maxZx, grid[j][i]);
}
yz += maxYz;
zx += maxZx;
}
return xy + yz + zx;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | func projectionArea(grid [][]int) int {
xy, yz, zx := 0, 0, 0
for i, row := range grid {
maxYz, maxZx := 0, 0
for j, v := range row {
if v > 0 {
xy++
}
maxYz = max(maxYz, v)
maxZx = max(maxZx, grid[j][i])
}
yz += maxYz
zx += maxZx
}
return xy + yz + zx
}
|
| function projectionArea(grid: number[][]): number {
const xy: number = grid.flat().filter(v => v > 0).length;
const yz: number = grid.reduce((acc, row) => acc + Math.max(...row), 0);
const zx: number = grid[0]
.map((_, i) => Math.max(...grid.map(row => row[i])))
.reduce((acc, val) => acc + val, 0);
return xy + yz + zx;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13 | impl Solution {
pub fn projection_area(grid: Vec<Vec<i32>>) -> i32 {
let xy: i32 = grid
.iter()
.map(|row| row.iter().filter(|&&v| v > 0).count() as i32)
.sum();
let yz: i32 = grid.iter().map(|row| *row.iter().max().unwrap_or(&0)).sum();
let zx: i32 = (0..grid[0].len())
.map(|i| grid.iter().map(|row| row[i]).max().unwrap_or(0))
.sum();
xy + yz + zx
}
}
|