leetcode 第892题 三维形体的表面积 python解法
问题分析
第892题具体内容如下:
题目描述很简洁,就是去求空间中由多个立方体构成的结构的总表面积,这个题目比较麻烦的一点就是如果相邻位置有立方体存在的话,那么这么立方体的侧面积就会有一部分被掩盖,所以在考虑每个位置立方体表面时一定要注意相邻位置的立方体情况。
我的做法是将每行和每列单独拿出来观测,假设所给的二维数组如下:
以第一行[1, 0, 2]来举例子,先在第一个位置上(1),由于这个位置左边没有立方体,所以左边的表面全部存在,然后移到第二个位置(0),0比前面的1小,说明前面的立方体比当前位置的立方体高,高出的部分就是露出来的表面,所以这里在返回结果上加1-0;最后是位置2(5),位置2的数要比位置1大,说明这个位置左边会有一部分露出来,露出来的表面积为5-0=5。最后还有一点比较重要那就是最右边的立方体的右表面没有计算入内,但是没有任何遮挡,所以直接可以加上返回值。
这样第一列遍历完了,接下来是第二列,第三列等等。每一行也是这样操作。当然,这还不是最后的总面积,因为还有上面和下面两个表面,这个比较好计算,只要我们在遍历时,发现某个位置上存在立方体,就可以直接在返回结果上加2.
在遍历中还有一个技巧就是,列号和行号相同的一列(行)可以同时遍历,因为列数和行数相等。比如最外层遍历为k(0<=n),内层为i(0<=i<n),那么grid[k][i]说明现在遍历的是第k行,而grid[i][k]表示的就是遍历的是第k列,所以在同一次遍历中就完成了一行和一列的操作。
源码
class Solution:
def surfaceArea(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
n = len(grid)
if n == 1:
return 6 + 4 * (grid[0][0] - 1)
ret = 0
for k in range(n):
left, forward, j = 0, 0, 0
while j < n:
if grid[k][j]: # 如果当前位置有立方体存在,那么加上上表面和下表面
ret += 2
if grid[k][j] > left: # 当前位置的立方体高于左边的位置
ret += grid[k][j] - left
else: # 当前位置的立方体低于左边的位置
ret += left- grid[k][j]
if grid[j][k] > forward: # 当前位置的立方体高于前面的位置
ret += grid[j][k] - forward
else: # 当前位置的立方体低于后面的位置
ret += forward - grid[j][k]
left, forward, j = grid[k][j], grid[j][k], j + 1
ret += grid[k][j-1] # 加上每一行最右侧的面积
ret += grid[j-1][k] # 加上每一行最下面的面积
return ret