​LeetCode刷题实战554:砖墙

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 砖墙,我们先来看题面:

https://leetcode-cn.com/problems/brick-wall/

There is a rectangular brick wall in front of you with n rows of bricks. The ith row has some number of bricks each of the same height (i.e., one unit) but they can be of different widths. The total width of each row is the same.

Draw a vertical line from the top to the bottom and cross the least bricks. If your line goes through the edge of a brick, then the brick is not considered as crossed. You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks.

Given the 2D array wall that contains the information about the wall, return the minimum number of crossed bricks after drawing such a vertical line.

你的面前有一堵矩形的、由 n 行砖块组成的砖墙。这些砖块高度相同(也就是一个单位高)但是宽度不同。每一行砖块的宽度之和相等。

你现在要画一条 自顶向下 的、穿过 最少 砖块的垂线。如果你画的线只是从砖块的边缘经过,就不算穿过这块砖。你不能沿着墙的两个垂直边缘之一画线,这样显然是没有穿过一块砖的。

给你一个二维数组 wall ,该数组包含这堵墙的相关信息。其中,wall[i] 是一个代表从左至右每块砖的宽度的数组。你需要找出怎样画才能使这条线 穿过的砖块数量最少 ,并且返回 穿过的砖块数量 。

示例       

0904868f91b84538f2cdf628394177f3.png                 

示例 1:
输入:wall = [[1,2,2,1],[3,1,2],[1,3,2],[2,4],[3,1,2],[1,3,1,1]]
输出:2

示例 2:
输入:wall = [[1],[1],[1]]
输出:3

解题

https://www.cnblogs.com/Mrsdwang/p/14760420.html

因为我们要穿过墙,并且要穿过的砖块最少,因此我们应该从从墙缝最多的地方穿过。

那么问题来了,我们如何求得墙缝呢?

每行每个砖头有自己的宽度,墙缝存在两墙块之间,并且每行的总宽度相同,因此我们通过前缀和,来等效求解墙缝。

假设一行砖头宽度为[1,2,2,1],那么缝隙的标号就可以设定为1,1+2,1+2+2.因此该行的墙缝为1,3,5号。为什么没有1+2+2+1=6号呢?因为这是墙的宽度,在边缘不会有任何砖头阻挡,所以题目也说了不能沿墙的垂直边缘穿过。

那么我们整面墙的墙缝号出现的次数越多,我们穿过的砖头就越少。所以我们通过hash表来记录墙缝号和其出现的次数。我们选最大的,并获取其墙缝号,最后遍历每行砖块是否没有出现过这个墙缝号,出现就跳过这行。否则就记一次穿过了一块砖,并跳过这行。

class Solution {
public:
    int leastBricks(vector<vector<int>>& wall) {
        unordered_map<int,int> fengxicount;
        int height = wall.size();
        int maxfengxi=0;
        int fengxi=0;
        int width_all = 0;
        int width0 = wall[0].size();
        for(int i=0;i<width0;++i){
            width_all+=wall[0][i]; //计算砖墙的边缘
        }
        for(int i=0;i<height;i++){
            int width = wall[i].size();
            int presum=0;
            for(int j=0;j<width;++j){
                presum+=wall[i][j];
                if(presum==width_all) break; //跳过墙垂直边缘的情况
                fengxicount[presum]++;
                if(maxfengxi<fengxicount[presum]){ //获取出现频率最高的墙缝号
                    fengxi = presum;
                    maxfengxi=fengxicount[presum];
                }
            }
        }
        int res=0;
        for(int i=0;i<height;++i){
            int width = wall[i].size();
           int presum=0;
            for(int j=0;j<width;++j){
                presum+=wall[i][j];

                //每行墙缝号只有小于,大于出现频率最高的墙缝号,可能会等于,所以等于就不会穿过砖头,如果从小于直接到了大于,那么就算穿过了砖块。
                if(presum==fengxi) { 
                    break;
                }
                if(presum>fengxi){
                    res++;
                    break;
                } 
            }
        }
        return res;
    }
};

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。

上期推文:

LeetCode1-540题汇总,希望对你有点帮助!

LeetCode刷题实战541:反转字符串 II

LeetCode刷题实战542:01 矩阵

LeetCode刷题实战543:二叉树的直径

LeetCode刷题实战544:输出比赛匹配对

LeetCode刷题实战545:二叉树的边界

LeetCode刷题实战546:移除盒子

LeetCode刷题实战547:省份数量

LeetCode刷题实战548:将数组分割成和相等的子数组

LeetCode刷题实战549:二叉树中最长的连续序列

LeetCode刷题实战550:游戏玩法分析 IV

LeetCode刷题实战551:学生出勤记录 I

LeetCode刷题实战552:学生出勤记录 II

LeetCode刷题实战553:最优除法

5efba51fbe79db5d41612b78db9d3565.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值