题目链接:this
解答链接:this
解题思路:对于v = grid[i][j],其表面积为s = 2 + v*4 。接下来只要在判断其相邻四个方向有没有放置立方体,有的话减去重合的面积即可。
class Solution(object):
def surfaceArea(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
res = 0
for i in range(len(grid)):
for j in range(len(grid[i])):
if grid[i][j] == 0:
continue
area = 2 + 4 * grid[i][j]
if i-1 >= 0:
area -= min(grid[i-1][j],grid[i][j])
if j-1 >= 0:
area -= min(grid[i][j],grid[i][j-1])
if i + 1 < len(grid):
area -= min(grid[i][j],grid[i+1][j])
if j + 1 < len(grid[i]):
area -= min(grid[i][j],grid[i][j+1])
res += area
return res
java 版本:
思路依然一样,
思路
让我们试着计算 v = grid[i][j] 所贡献的表面积。
当 v > 0 时,顶面和底面的面积之和为 2。
然后,对于列 grid[i][j] 的每一侧(西,北,东,南),值为 nv 的相邻单元意味着这些方块贡献了 max(v - nv, 0) 的面积。
例如,对于 grid = [[1, 5]],grid[0][1] 贡献的表面积是 2 + 5 + 5 + 5 + 4。其中 2 来自顶部和底部;5 来自北、东、南三面;4 来自西面,其中 1 个单位被邻列覆盖。
算法
对于每个 v = grid[r][c] > 0,计算 ans += 2,对于 grid[r][c] 附近的每个相邻值 nv 还要加上 ans += max(v - nv, 0)。
class Solution{
public int surfaceArea(int [][] grid){
// 用dr,dc 实现对前后左右的单元格的指向
int [] dr= new int[]{0,1,0,-1};
int [] dc= new int[]{1,0,-1,0};
int N=grid.length;//行数
int ans=0;
for(int r=0;r<N;++r){
for(int c=0;c<N;++c){
if(grid[r][c]>0){//如果该放歌内游方块,则顶面和底面的面积之和为 2
ans+=2;
}
//nr,nc 的组合(0,1)、(1,0)(0,-1)、(-1,0),保证了该方块区域的上下左右的指向
for(int k=0;k<4;k++){
int nr=r+dr[k];
int nc=c+dc[k];
int nv=0;
if(0<=nr &&nr<N&&0<=nc&&nc<N)
nv=grid[nr][nc];
ans+=Math.max(grid[r][c]-nv,0)
}
}
}
return ans;
}
}