On a `N * N` grid, we place some `1 * 1 * 1 `cubes that are axis-aligned with the x, y, and z axes.

Each value v = grid[i][j] represents a tower of v cubes placed on top of grid cell (i, j).

Now we view the projection of these cubes onto the xy, yz, and zx planes.

A projection is like a shadow, that maps our 3 dimensional figure to a 2 dimensional plane.

Here, we are viewing the "shadow" when looking at the cubes from the top, the front, and the side.

Return the total area of all three projections.

Example 1:

Input: [[2]]
Output: 5

Example 2:

Input: [[1,2],[3,4]]
Output: 17
Explanation:
Here are the three projections ("shadows") of the shape made with each axis-aligned plane.



Example 3:

Input: [[1,0],[0,2]]
Output: 8

Example 4:

Input: [[1,1,1],[1,0,1],[1,1,1]]
Output: 14

Example 5:

Input: [[2,2,2],[2,1,2],[2,2,2]]
Output: 21

Note:

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

这道题给了我们一个二维数组 grid,用来表示一个 3D 物体形状,表示方法是 grid[i][j] 表示在 (i, j) 位置上的高度,就像垒积木一样,累出了一个三维物体。然后让我们计算三个方向的投影面积之和,所谓的三个方向分别是上方 Top,前方 Front,和侧方 Side。用过一些三维建模软件(例如 Maya, 3DMax)的同学,对这个应该不陌生。我们先来考虑正上方投影面积如何计算,由于题目中说了 grid 数组的宽和高相等,那么上方投影就是一个正方形,前提是每个 grid[i][j] 的值都大于0的话。因为若 grid 数组中有0存在,则表示正方形投影会缺少了一块。由于这个大的正方形投影是由 nxn 个小的正方形组成,那么实际上我们只要统计出小正方形的个数,那么大正方形投影的面积也就知道了(是不有点微积分的感觉)。所以我们在遍历的过程中,只要判断若 grid[i][j] 大于0,则结果 res 自增1即可。下面再来考虑另外两个方向的投影怎么计算,另两个方向的投影的可能是不规则图形,参见题目中给的那个图,如果仔细观察的话,其投影图像的每个阶段的高其实就是各行或各列中的最大值,这也不难理解,就像城市中耸立的高度不同的大楼,若要描出城市的轮廓,那么描出来的肯定都是每个位置上最高建筑物的轮廓。那么问题就变成了累加各行各列的最大值。我们实际上在一次遍历中就能完成,使用了一个小 trick,那就是在第二层 for 循环中,行最大值 rowMax 就是不断用 grid[i][j] 来更新,而列最大值 colMax 就是不断用 grid[j][i] 来更新,巧妙的交换i和j,实现了目标。然后分别把更新出来的行列最大值加到结果 res 中即可,参见代码如下:

class Solution {
public:
int projectionArea(vector<vector<int>>& grid) {
int n = grid[0].size(), res = 0;
for (int i = 0; i < n; ++i) {
int rowMax = 0, colMax = 0;
for (int j = 0; j < n; ++j) {
if (grid[i][j] > 0) ++res;
rowMax = max(rowMax, grid[i][j]);
colMax = max(colMax, grid[j][i]);
}
res += rowMax + colMax;
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/883

参考资料:

https://leetcode.com/problems/projection-area-of-3d-shapes/

https://leetcode.com/problems/projection-area-of-3d-shapes/discuss/156726/C%2B%2BJavaPython-Straight-Forward

https://leetcode.com/problems/projection-area-of-3d-shapes/discuss/156771/11-line-1-pass-Java-code-and-explanation-of-the-problem-time-O(N-2)-space-O(1).

[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)

[LeetCode] 883. Projection Area of 3D Shapes 三维物体的投影面积的更多相关文章

  1. LeetCode 883 Projection Area of 3D Shapes 解题报告

    题目要求 On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z axes. ...

  2. Leetcode883.Projection Area of 3D Shapes三维形体投影面积

    在 N * N 的网格中,我们放置了一些与 x,y,z 三轴对齐的 1 * 1 * 1 立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上. 现在,我们查 ...

  3. 【Leetcode_easy】883. Projection Area of 3D Shapes

    problem 883. Projection Area of 3D Shapes 参考 1. Leetcode_easy_883. Projection Area of 3D Shapes; 完

  4. [LeetCode] 892. Surface Area of 3D Shapes 三维物体的表面积

    On a N * N grid, we place some 1 * 1 * 1 cubes. Each value v = grid[i][j] represents a tower of v cu ...

  5. 883. Projection Area of 3D Shapes

    问题 NxN个格子中,用1x1x1的立方体堆叠,grid[i][j]表示坐标格上堆叠的立方体个数,求三视图面积. Input: [[1,2],[3,4]] Output: 17 Explanation ...

  6. 【LeetCode】883. Projection Area of 3D Shapes 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数学计算 日期 题目地址:https://leetc ...

  7. [LeetCode&Python] Problem 883. Projection Area of 3D Shapes

    On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z axes. Each ...

  8. 【leetcode】883. Projection Area of 3D Shapes

    题目如下: 解题思路:分别求出所有立方体的个数,各行的最大值之和,各列的最大值之和.三者相加即为答案. 代码如下: class Solution(object): def projectionArea ...

  9. [Swift]LeetCode883. 三维形体投影面积 | Projection Area of 3D Shapes

    On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z axes. Each ...

随机推荐

  1. Windows重要的win键

    win+↓ 当前窗口操作,多按几下就缩没了(同理,其他箭头也一样) win+e 打开此电脑 win+v 展开剪切板 win+k 访问蓝牙 win+a win10的通知 win+d (切到桌面,再用能切 ...

  2. Kubernetes RBAC授权普通用户对命名空间访问权限

    Kubernetes RBAC授权普通用户对命名空间访问权限 官方文档:https://www.cnblogs.com/xiangsikai/p/11413970.html kind: Role ap ...

  3. 记录一个终端入网小助手的bug

    背景:技术leader拿到一台超薄笔记本,系统标准化安装,笔记本一开机风扇嗡嗡响,键盘也开始发烫,资源占用排名前三的进程都是终端管理软件,一下子就找上门了.处理:进程分析发现异常,卸载入网小助手后恢复 ...

  4. 【题解】Dvoniz [COCI2011]

    [题解]Dvoniz [COCI2011] 没有传送门,只有提供了数据的官网. [题目描述] 对于一个长度为 \(2*K\) 的序列,如果它的前 \(K\) 个元素之和小于等于 \(S\) 且后 \( ...

  5. 【java】【guava】Google Guava的splitter用法

    Google Guava的splitter,分割字符串的用法 package com.sxd.swapping.guava; import com.google.common.base.CharMat ...

  6. 练手WPF(一)——模拟时钟与数字时钟的制作(下)

    继续数字时钟.上一篇写好了数字笔划专用的DigitLine类.现在是时候使用它了.下面对一些主要代码进行说明. 打开MainWindow.xaml.cs文件: (1)添加字段变量 // 数字时钟字段定 ...

  7. Java自学-集合框架 ArrayList常用方法

    ArrayList常用方法 步骤 1 : 增加 add 有两种用法: 第一种是直接add对象,把对象加在最后面 heros.add(new Hero("hero " + i)); ...

  8. 打造游戏金融小程序行业测试标准腾讯WeTest携各专家共探品质未来

    在获客成本不断上升的时代里,产品品质愈发是互联网应用的决胜标准.随着用户需求更加多样,开发者不仅要深挖应用功能,更需要面向业务所在领域,建立全面.专业的测试架构,掌控开发进度.提高开发效率,才能在互联 ...

  9. js 加密混淆工具

    访问路径:https://www.sojson.com/javascriptobfuscator.html

  10. Java内存模型。

    Java内存模型: 准备知识:缓存,缓存一致性,硬件缓冲区:写缓冲区.无效化队列,内存重排序,内存屏障. 1.Java内存模型概念. 首先,在并发的情况下,计算机系统必须解决这样两个问题:第一,一个处 ...