On a N * N
grid, we place some 1 * 1 * 1
cubes.html
Each value v = grid[i][j]
represents a tower of v
cubes placed on top of grid cell (i, j)
.git
Return the total surface area of the resulting shapes.github
Example 1:数组
Input: [[2]] Output: 10
Example 2:3d
Input: [[1,2],[3,4]] Output: 34
Example 3:code
Input: [[1,0],[0,2]] Output: 16
Example 4:htm
Input: [[1,1,1],[1,0,1],[1,1,1]] Output: 32
Example 5:blog
Input: [[2,2,2],[2,1,2],[2,2,2]] Output: 46
Note:leetcode
1 <= N <= 50
0 <= grid[i][j] <= 50
这道题给了咱们一个二维数组 grid,其中 grid[i][j] 表示在位置 (i,j) 上累计的小正方体的个数,实际上就像搭积木同样,由这些小正方体来组成一个三维的物体,这里让咱们求这个三维物体的表面积。咱们知道每一个小正方体的表面积是6,若在同一个位置累加两个,表面积就是10,三个累加到了一块儿就是14,实际上是有规律的,n个小正方体累在一块儿,表面积是 4n+2。如今不单单是累加在一个小正方体上,而是在 nxn 的区间,累加出一个三维物体。因为以前作过那道三维物体投影的题 Projection Area of 3D Shapes,因此博主很思惟定势的想到是否是也跟投影有关,而后又想固然的认为三维物体每个面的面积就是该方向的投影,那么咱们把三个方向的投影之和算出来,再乘以2不就是表面积了么?实际上这种方法是错误的,就拿题目中的例子4来讲,当中间的小方块缺失了以后,实际上缺失的地方会产生出四个新的面,而这四个面是应该算在表面积里的,可是用投影的方法是无法算进去的。无奈只能另辟蹊径,实际上这道题正确的思路是一个位置一个位置的累加表面积,就相似微积分的感受,前面提到了当n个小正方体累到一块儿的表面积是 4n+1,而这个n就是每一个位置的值 grid[i][j],当你在旁边紧挨着再放一个累加的物体时,两者就会产生重叠,重叠的面数就是两者较矮的那堆正方体的个数再乘以2,明白了这一点,咱们就能够从 (0,0) 位置开始累加,先根据 grid[0][0] 的值算出若仅有该位置的三维物体的表面积,而后向 (0,1) 位置遍历,一样要先根据 grid[0][1] 的值算出若仅有该位置的三维物体的表面积,跟以前 grid[0][0] 的累加,而后再减去遮挡住的面积,经过 max(grid[0][0],grid[0][1])x2 来获得,这样每次能够计算出水平方向的遮挡面积,同时还须要减去竖直方向的遮挡面积 min(grid[i][j],grid[i-1][j])x2,这样才能算出正确的表面积,参见代码以下:get
class Solution { public: int surfaceArea(vector<vector<int>>& grid) { int n = grid.size(), res = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (grid[i][j] > 0) res += 4 * grid[i][j] + 2; if (i > 0) res -= min(grid[i][j], grid[i - 1][j]) * 2; if (j > 0) res -= min(grid[i][j], grid[i][j - 1]) * 2; } } return res; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/892
相似题目:
参考资料: