There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks.
The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each brick in this row from left to right.
If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how to draw the line to cross the least bricks and return the number of crossed bricks.
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.
Example:
Input:
[[1,2,2,1],
[3,1,2],
[1,3,2],
[2,4],
[3,1,2],
[1,3,1,1]]
Output: 2
非常有趣的题,刚开始看到题也是比较懵逼,可能是我做的题不多的原因。但是后来想明白了也是比较简单的。题的大概意思就是算出从墙缝中穿过的话,最少经过的层次,比如说图中的红线,就只需要穿过两层。
我们从这个图中可以计算一下一共有多少种情况(不会PS,没办法去掉红线。。。用粉线来分析):
1:
这个情况相当于是从粉线将其分开,左边宽度是1,右边宽度是5。然后看每一行的,其中1、3、6行都是左边正好都是1,不需要穿过。所以如果按照这种方法来的话,总共需要穿过3层,也就是总的层数6减去不需要穿过的层数(这里是1,左边是1的一共有三层)等于3。
2:
这种情况就是需要左边宽度为2,右边宽度为4。相当于除了第4层之外,其他的都需要穿过。那就是总层数6减去1等于5.
3:
这种情况就是左边宽度为3,右边宽度为3。其中第1、2、5行左边都正好是3,所以不需要穿过。那么需要穿过的层数就是总层数6减去3,需要穿过3层。
4:
这种情况就是官方的图,也就是左边宽度为4,右边宽度为2。其中第2、3、5、6左边都正好是4,所以需要穿过的层数就是总层数减去4,需要穿过2层。
5:
最后一种情况,左边宽度为5,右边宽度为1。其中第1、6行左边正好是5,所以 需要穿过的就是总层数减去2,也就是4。
在这张图中一共就只有这5中情况,那么我们就可以从图中得到解题的方法了。我们只需要求出共有几层的左边宽度一样就行了,然后用总层数减去这个数字,得到的就是需要穿过的层数。比如说左边宽度为3,那么共有第1、2、5层左边宽度都是3,那么1、2、5层就不需要穿过了。总层数减去这个不需要穿过的层数就是需要穿过的层数。我们可以用一个map来记录左边宽度和共有几层左边宽度一样。比如左边宽度为1:<1,3>。需要注意的就是不能计算两边边缘的情况,比如图中就不需要计算左边宽度为0或者为6的情况。以下是代码,可以打开注释观察运行中的数据变化。
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
int leastBricks(vector<vector<int>>& wall) {
int maxBrick = wall.size();//最大的层次.
int minBrick = wall.size();//最小的层次,默认为最大层次。
unordered_map<int,int> width;//用来保存每个长度对应的个数。
int sum;//用来计算左边的砖的长度
for(int i = 0; i < wall.size(); i++) {//分别循环每层。
sum = 0;
for(int j = 0; j < wall[i].size() - 1; j++) {//分别比较每层里面的砖。需要减去1,因为不需要计算总的宽度。
sum += wall[i][j];//得到当前左边转的长度。
width[sum]++;//当前左边长度在map中+1.
//cout << sum << ", ";
//cout << width[sum] << "\n";
minBrick = min(minBrick,maxBrick - width[sum]);
}
//cout << endl << endl;
}
//cout << minBrick;
return minBrick;
}
};
int main() {
Solution s;
vector<vector<int>> wall;
vector<int> a1;
vector<int> a2;
vector<int> a3;
vector<int> a4;
vector<int> a5;
vector<int> a6;
/*a1.push_back(1);
a2.push_back(1);
a3.push_back(1);*/
a1.push_back(1);
a1.push_back(2);
a1.push_back(2);
a1.push_back(1);
a2.push_back(3);
a2.push_back(1);
a2.push_back(2);
a3.push_back(1);
a3.push_back(3);
a3.push_back(2);
a4.push_back(2);
a4.push_back(4);
a5.push_back(3);
a5.push_back(1);
a5.push_back(2);
a6.push_back(1);
a6.push_back(3);
a6.push_back(1);
a6.push_back(1);
wall.push_back(a1);
wall.push_back(a2);
wall.push_back(a3);
wall.push_back(a4);
wall.push_back(a5);
wall.push_back(a6);
s.leastBricks(wall);
}