LeetCode之554.砖墙

554. 砖墙

  • 题目
  • 分析
  • 代码

题目

你的面前有一堵方形的、由多行砖块组成的砖墙。 这些砖块高度相同但是宽度不同。你现在要画一条自顶向下的、穿过最少砖块的垂线。

砖墙由行的列表表示。 每一行都是一个代表从左至右每块砖的宽度的整数列表。

如果你画的线只是从砖块的边缘经过,就不算穿过这块砖。你需要找出怎样画才能使这条线穿过的砖块数量最少,并且返回穿过的砖块数量。

你不能沿着墙的两个垂直边缘之一画线,这样显然是没有穿过一块砖的。

示例:

输入: [[1,2,2,1],
      [3,1,2],
      [1,3,2],
      [2,4],
      [3,1,2],
      [1,3,1,1]]

输出: 2

提示:
每一行砖块的宽度之和应该相等,并且不能超过 INT_MAX。
每一行砖块的数量在 [1,10,000] 范围内, 墙的高度在 [1,10,000] 范围内, 总的砖块数量不超过 20,000。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/brick-wall
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析

这道题有个图,大家可以访问以上链接去LeetCode官网查看,这个图对这道题解释的比较清晰。

这道题我之前就做了,提交了4次,没一次过的,心态崩了,后来就没在做了。没想到今天刷的时候又碰到了它。想想不能总是逃避,迟早是要面对的,就参考题解把它给弄出来了。
在此记录一下今天小小地战胜了自己的逃避心理。

这道题思路其实也并不复杂,但是看到题的一瞬间真的不知道如何下手,看了评论后,有一种解法:统计出每一层墙的边界值,然后取数量最多的边界值即可。

例如:
第一层墙:1,2,2,1
边界值有:1,3,5(注意:边缘不能画线)

第二层墙:3,1,2
边界值有:3,4(注意:边缘不能画线)

以此类推。
当看到这个算法时我的第一反应是:每一行砖的数量如果过大,可能会导致运行时间过长而超时。
因为根据题目给出的条件:每一行砖块的宽度之和应该相等,并且不能超过 INT_MAX。,即每行砖块的宽度之和最大能达到26亿。如果每层都统计一下边界值,那妥妥的超时了。

然而,事情并不是我想的那样,把代码实现了之后发现并没有超时(打脸)。

思路是这样的:

  • 每个边界值用1个hashMap进行记录,key为边界值,value为该边界值出现的次数。
  • 每次都将出现次数最多的value记录下来(max)。该value可以抽象为:一条线从上往下画,不会经过砖的最大层数。 并且该值一定是小于层数的。
  • 最终结果需要统计这条线穿过了几块砖,则使用所有的层数 - max,因为每一层都只有可能经过一块砖。

代码

class Solution {
public:
    int leastBricks(vector<vector<int>>& wall) {
        int sum = 0;
        int max = 0;
        unordered_map<int, int> map;
        for (int i = 0; i < wall.size(); ++i) {
            sum = 0;
            for (int j = 0; j < wall[i].size() - 1; ++j) {
                sum += wall[i][j];
                ++map[sum];
                max = std::max(max, map[sum]);
            }
        }

        return wall.size() - max;
    }
};

你可能感兴趣的:(C++,leetcode)