题目
思路
什么是空隙?
首先需要理解一个隐含的条件,即空隙是不占宽度的,即宽度为1
和2
的中间存在空隙的两堵墙和宽度为3
的一堵墙的总宽度是相同的,墙的边缘就算作一个空隙。比如下面这个例子中,第一行的0,1,3
都是墙的边缘,均算作一个空隙,第二行0,3
是墙的边缘算作空隙。
pos 0 1 2 3
| 1 | 2 |
| 3 |
墙位置和空隙的位置
要计算某条线穿过的墙的数量,我们需要确定墙的位置,然而,墙是有宽度的,每堵墙都是一个范围,因此比较难以存储(需要存储起始和结束位置并且额外记录某个位置是墙的起始位置还是结束位置)和快速判断某条线是否穿过某堵墙。然而,根据上边的分析,我们知道空隙的位置是一个确定的值,如果我们计算出空隙的位置,并使用hash表存储,就可以快速的查找某条线(一个确定的位置)是否经过某个空隙。
一旦可以确定空隙的位置,以及能够快速查找某条线是否经过某个空隙,我们只需要遍历所有的行的空隙,将处在同一条线上的空隙总数统计起来,最后找到空隙数量最大的那条线即可。
代码
class Solution {
public:
int leastBricks(vector<vector<int>>& wall) {
// 统计各条线的空隙总数
unordered_map<int, int> gap;
int gap_max = 0;
for(vector<int> row : wall) {
// 记录前行的空隙位置
int gap_pos = 0;
// i < row.size() - 1是因为我们不需要最后一个空隙
for(int i=0; i<row.size() - 1; i++) {
int brick_len = row[i];
// 当前行的空隙位置(砖块的边缘即为空隙)
gap_pos += brick_len;
// 经过该空隙的线是否同上边行的空隙
if (gap.count(gap_pos) == 0) {
// 没有经过则标记该条线经过的空隙为1
gap[gap_pos] = 1;
} else {
// 否则该条线经过的空隙数加1
gap[gap_pos]++;
}
}
}
for(auto p = gap.begin(); p != gap.end(); p++) {
if (p->second > gap_max) {
gap_max = p->second;
}
}
return wall.size() - gap_max;
}
};