Skip to content

Files

Latest commit

4d6c701 · Feb 21, 2024

History

History

0883.Projection Area of 3D Shapes

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Apr 13, 2021
Feb 21, 2024
Feb 21, 2024
Aug 13, 2022
Oct 31, 2023
Apr 26, 2022
Apr 26, 2022
Feb 19, 2024
Feb 19, 2024

English Version

题目描述

在 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
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;
    }
}
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;
    }
};
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;
}
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
    }
}