LeetCode 892.三维形体的表面积-简单
1.题目
在 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.解题
方法一:在总面积中减去隐藏的面积
- 总面积是立方体的个数乘以6
- 上下堆叠会隐藏面积,k个正方体的上下堆叠会隐藏k-1个面(1个面对应2份面积)
- 左右相叠会隐藏面积,以左右中立方体数较少的为准,例如2个立方体和3个立方体左右相叠,会隐藏2个面
- 前后相叠同理
- 最后的表面积应该是总面积减去所有隐藏面对应的面积
class Solution:
def surfaceArea(self, grid: List[List[int]]) -> int:
"""
:type: grid: List[List[int]] # 矩阵网络,嵌套List
:rtype: int # 表面积
"""
N = len(grid) # 矩阵的行数(列数)
n = 0 # 立方体总个数
n1 = 0 # 因为上下相叠而隐藏的面(1面对应2份表面积)
for i in range(N):
for j in range(N):
n = n + grid[i][j]
if grid[i][j] > 1:
n1 = n1 + grid[i][j] - 1
n2 = 0 # 因为左右相叠而隐藏的面(1面对应2份表面积)
for i in range(N):
for j in range(N-1):
n2 = n2 + (grid[i][j] if grid[i][j] < grid[i][j+1] else grid[i][j+1])
n3 = 0 # 因为前后相叠而隐藏的面(1面对应2份表面积)
for j in range(N):
for i in range(N-1):
n3 = n3 + (grid[i][j] if grid[i][j] < grid[i+1][j] else grid[i+1][j])
S = n * 6 - (n1 + n2 + n3) * 2
return S
方法二:优化版本
- 逐个扫描网格,同一网格中有n个立方体,则除外上下堆叠隐藏的面,应该有4n+2份表面积
- 从第二行开始(即i>0)的立方体,需要考虑与上一行堆叠隐藏的面
- 从第二列开始(即j>0)的立方体,需要考虑与前一列堆叠隐藏的面
- 复杂度分析:
时间复杂度O(Nˆ2):两层循环
空间复杂度O(1)
class Solution:
def surfaceArea(self, grid: List[List[int]]) -> int:
"""
:type: grid: List[List[int]] # 矩阵网络,嵌套List
:rtype: int # 表面积
"""
N = len(grid) # 矩阵的行数(列数)
S = 0
for i in range(N):
for j in range(N):
if grid[i][j] > 0:
S += 4 * grid[i][j] + 2
if i > 0:
S -= min(grid[i][j],grid[i-1][j])*2
if j > 0:
S -= min(grid[i][j],grid[i][j-1])*2
return S