在 N * N 的网格上,我们放置一些 1 * 1 * 1 的立方体。
每个值 v = grid[i][j]
表示 v 个正方体叠放在对应单元格 (i, j) 上。
请你返回最终形体的表面积。
示例 1: 输入:[[2]] 输出:10
示例 2: 输入:[[1,2],[3,4]] 输出:34
示例 3: 输入:[[1,0],[0,2]] 输出:16
示例 4: 输入:[[1,1,1],[1,0,1],[1,1,1]] 输出:32
示例 5: 输入:[[2,2,2],[2,1,2],[2,2,2]] 输出:46
提示:
1 <= N <= 50
0 <= grid[i][j] <= 50
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/surface-area-of-3d-shapes
public int surfaceArea(int[][] grid) {
int sum = 0; // 用来记录几个格子上有放立方体
int n = grid.length;
for(int i = 0; i < n; i++){
if(grid[i][0] != 0) sum += 2;
for(int j = 1; j < n; j++){
if(grid[i][j] != 0) sum += 2;
sum += Math.abs(grid[i][j] - grid[i][j - 1]) + Math.abs(grid[j][i] - grid[j - 1][i]);
}
sum += grid[i][n - 1] + grid[i][0] + grid[0][i] + grid[n - 1][i];
}
return sum;
}
思路分析:
- 这个题明首先,上下底面的表面积就是2乘以放了方块的格子数量。侧面积会比较麻烦,但是对于N*N的矩形区域,行列式等价的。
- 从空间几何体描述的角度来看,左右侧面的处理方式与前后面的方式一样。因为旋转90度,左右就变成前后,前后就变成左右了。所以,可以由图示来看一下,侧面表面积的处理方式。
- 图示展示的是一行(左右侧面)的处理方式,该行的主视图,计算该行的侧面积。
- 对于每一行,每一列都进行相同处理即可。同时,记录有多少个格子放了立方体,以便得到上下底面积。
- 所以这是一个遍历,时间复杂度为$O(n^2)$,空间复杂度为$O(1)$。
代码解释:
- 代码解释,第5及第7行,是用于统计有多少个格子放置了立方体,放置了立方体的单个格子,上下底面对表面积的贡献为2。
- 在图示中,进行内部侧面积计算时,使用了
grid[i][j - 1]
(针对行),或者gird[j -1][i]
(针对列),所以第6行的内循环从j = 1
开始。 - 第8行,针对内部会被遮盖的立方体贡献的表面积的计算。第十行则是最外侧没有遮盖的表面的面积贡献(前后左右四个方向,所以会有四个加数)。
运行结果:
- 执行用时 :3 ms, 在所有 Java 提交中击败了98.69%的用户
- 内存消耗 :41 MB, 在所有 Java 提交中击败了90.44%的用户