三维形体的表面积--算法中的几何思想

0x01.问题

N * N 的网格上,我们放置一些 1 * 1 * 1 的立方体。
每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。
请你返回最终形体的表面积。
输入示例:[[1,1,1],[1,0,1],[1,1,1]]
输出示例:32

C++函数形式:   int surfaceArea(vector<vector<int>>& grid)

0x02.简要分析

初一看,这个问题似乎有点复杂,因为一些正方体重叠起来会产生非常多的重叠空间,我们怎么去去掉这些重复的面积呢,或者,我怎么知道到底有没有重复呢?

我们先来看一个图:
在这里插入图片描述
怎么样,是不是发现没有任何思路。

别怕,我们先找一个标志,然后慢慢的去清理去重的思路。

  • 第一点,当一个方格上方有n个正方体的时候,产生了多大的表面积呢,先不考虑重叠的部分。

在这里插入图片描述
很容易发现,当一个格子上有n个正方体的时候,我们一共产生了两个底面(上底面和下底面),n*4个侧面,总共就是n*4+2的面积,这是不考虑重复的情况。

  • 第二点,重叠的部分该怎么去掉呢?

首先,我们要清楚,每一个格子上产生的重叠,和哪些格子有关,没错,就是上下左右,四个都有关,而且是在矩阵中,最开始的那部分的左边和上边肯定不要考虑,快要结束的那部分右边和下边不要考虑,我们怎样做到遍历一遍,就能统一一个标准,去掉所有的重复呢?

那就是对每一个格子只考虑左边和上边产生的影响,最开始的不考虑,因为通过遍历,它的右边和下边,最终会成为其它格子的左边和上边,而去重只需要去一次,而且这样最靠近末尾的部分的右边和下边不要考虑,因为没有重叠。

  • 第三点,重叠部分面积的计算。

重叠的面积就是两个共同有的,也就是由最矮的那个格子决定的,是最矮格子的两倍,也就是min(v1,v2)*2

到这里,我们就只需要一次遍历就可以求出来了。

0x03.解决代码–几何思想

class Solution {
public:
    int surfaceArea(vector<vector<int>>& grid) {
        int ans=0;
        for(int i=0;i<grid.size();i++){
            for(int j=0;j<grid.size();j++){
                int temp=grid[i][j];
                if(temp==0) continue;
                ans+=temp*4+2;//一列正方体产生的表面积
                ans-=i>0?min(grid[i-1][j],temp)*2:0;//减去左边重叠的面积
                ans-=j>0?min(grid[i][j-1],temp)*2:0;//减去上边重叠的面积
            }
        }
        return ans;
    }
};

ATFWUS --Writing By 2020–03–25

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATFWUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值