题干
在 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
想法
参考她的图画的很好
根据小学奥数知识我们知道这个题的难点就是确认重叠的部分的面积
即最终结果=正方体总数量6-2重叠面个数
因为题给的是每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。
也就是说上下重叠的情况是确定的,每v个正方体有v-1个面重叠。
侧面四个也一样,侧面相邻的话,高度低的那一个就是侧面的重叠大小。
所以看代码吧
扫描二维码关注公众号,回复:
10974632 查看本文章
Java代码
package daily;
public class SurfaceArea {
public int surfaceArea(int[][] grid) {
int n=grid.length;
//正方体数量
int cubeNum=0;
//面数量
int face=0;
for (int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(grid[i][j]>0){
//记录正方体数量
cubeNum+=grid[i][j];
// 面数量
face+=grid[i][j]-1;
}
if(i>0){
//侧面数量 下同
face+=Math.min(grid[i][j],grid[i-1][j]);
}
if(j>0){
face+=Math.min(grid[i][j-1],grid[i][j]);
}
}
}
return cubeNum*6-face*2;
}
public static void main(String [] args){
SurfaceArea surfaceArea= new SurfaceArea();
int [][]test={{1,1,1},{1,0,1},{1,1,1}};
int res=surfaceArea.surfaceArea(test);
System.out.println(res);
}
}
leetcode上更快的直接相加法
class Solution {
public int surfaceArea(int[][] grid) {
int result = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
result += getFaceNum(grid, i, j);
}
}
return result;
}
private int getFaceNum(int[][] grid, int i, int j) {
if (grid[i][j] == 0){
return 0;
}
int faceNum = grid[i][j] * 4 + 2;
if (i - 1 >= 0) {
faceNum -= Math.min(grid[i][j], grid[i - 1][j]);
}
if (j - 1 >= 0) {
faceNum -= Math.min(grid[i][j], grid[i][j - 1]);
}
if (i + 1 < grid.length) {
faceNum -= Math.min(grid[i][j], grid[i + 1][j]);
}
if (j + 1 < grid[0].length) {
faceNum -= Math.min(grid[i][j], grid[i][j + 1]);
}
return faceNum;
}
}