力扣 554. 砖墙

题目说明

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

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

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

  • 提示:
    • n == wall.length
    • 1 <= n <= 104
    • 1 <= wall[i].length <= 104
    • 1 <= sum(wall[i].length) <= 2 * 104
    • 对于每一行 isum(wall[i]) 应当是相同的
    • 1 <= wall[i][j] <= 231 - 1

示例

例1

image.png

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

例2

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

笔者理解

此题是一道哈希算法问题,在力扣题库中被定义为中等题。

解法

当笔者阅读完此题后,发现此题用哈希表来存储各砖块能到达的位置即可快速求解,让我们来看看具体如何实现的吧。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public int leastBricks(List<List<Integer>> wall) {
// 用map来存储各砖块能到的长度及出现次数
// 出现共同长度最多的地方就是题解
HashMap<Integer, Integer> map = new HashMap();
int hight = wall.size();

for (int i = 0; i < hight; i++) {
int sum = 0;
// 此处j的范围减一是因为墙的右边界不能作为比较
for (int j = 0; j < wall.get(i).size() - 1; j++) {
sum += wall.get(i).get(j);
if (map.getOrDefault(sum, 0) == 0) {
map.put(sum, 1);
}
else {
map.put(sum, map.get(sum) + 1);
}
}
}

int max = 0;

for (Integer v: map.values()) {
max = Math.max(max, v);
}

// 墙厚度减去共同长度的板砖数
return hight - max;
}

时间和空间效率都还行,可见此解法还比较适合此题;

image-20210502100922880

总结

本题是今天的每日一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。