Medium
题目描述
你的面前有一堵矩形的砖墙,由 n 行砖块组成。第 i 行有若干块砖,每块砖的高度相同(即一个单位),但它们的宽度可以不同。每一行的总宽度都相同。
从顶部到底部画一条垂直线,穿过最少的砖块。如果你的线穿过砖块的边缘,那么该砖块不被认为是穿过的。你不能沿着墙的两个垂直边缘中的一个画线,在这种情况下,线显然不会穿过任何砖块。
给定包含墙信息的二维数组 wall,返回画这样一条垂直线后穿过的砖块的最小数量。
示例 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
提示:
n == wall.length1 <= n <= 10^41 <= wall[i].length <= 10^41 <= sum(wall[i].length) <= 2 * 10^4- 对于每一行 i,
sum(wall[i])都相同 1 <= wall[i][j] <= 2^31 - 1
解题思路
解题思路
这道题的关键在于找到一条垂直线能够经过最多的砖块缝隙(边缘),从而穿过最少的砖块。
基本思路
- 观察规律:如果一条垂直线经过了 k 个砖块的缝隙,那么它就只需要穿过
n-k个砖块(其中 n 是墙的行数) - 问题转化:原问题等价于找到经过最多缝隙的垂直线位置
算法步骤
- 记录缝隙位置:遍历每一行砖块,计算每个砖块的累计宽度(除了最后一块砖,因为不能画在墙的边缘)
- 统计频次:使用哈希表记录每个位置出现的缝隙次数
- 找最大值:找到出现次数最多的缝隙位置
- 计算结果:用总行数减去最大缝隙次数
复杂度分析
- 时间复杂度:O(sum(wall[i].length)),需要遍历所有砖块
- 空间复杂度:O(总缝隙数),哈希表存储缝隙位置
这种方法避免了枚举所有可能的垂直线位置,而是直接统计有意义的缝隙位置,效率很高。
代码实现
class Solution {
public:
int leastBricks(vector<vector<int>>& wall) {
unordered_map<int, int> edgeCount;
for (const auto& row : wall) {
int position = 0;
// 遍历除了最后一块砖之外的所有砖
for (int i = 0; i < row.size() - 1; i++) {
position += row[i];
edgeCount[position]++;
}
}
int maxEdges = 0;
for (const auto& pair : edgeCount) {
maxEdges = max(maxEdges, pair.second);
}
return wall.size() - maxEdges;
}
};
class Solution:
def leastBricks(self, wall: List[List[int]]) -> int:
edge_count = {}
for row in wall:
position = 0
# 遍历除了最后一块砖之外的所有砖
for i in range(len(row) - 1):
position += row[i]
edge_count[position] = edge_count.get(position, 0) + 1
max_edges = max(edge_count.values()) if edge_count else 0
return len(wall) - max_edges
public class Solution {
public int LeastBricks(IList<IList<int>> wall) {
Dictionary<int, int> edgeCount = new Dictionary<int, int>();
foreach (var row in wall) {
int position = 0;
// 遍历除了最后一块砖之外的所有砖
for (int i = 0; i < row.Count - 1; i++) {
position += row[i];
if (edgeCount.ContainsKey(position)) {
edgeCount[position]++;
} else {
edgeCount[position] = 1;
}
}
}
int maxEdges = 0;
foreach (var pair in edgeCount) {
maxEdges = Math.Max(maxEdges, pair.Value);
}
return wall.Count - maxEdges;
}
}
/**
* @param {number[][]} wall
* @return {number}
*/
var leastBricks = function(wall) {
const edgeCount = new Map();
for (const row of wall) {
let position = 0;
// 遍历除了最后一块砖之外的所有砖
for (let i = 0; i < row.length - 1; i++) {
position += row[i];
edgeCount.set(position, (edgeCount.get(position) || 0) + 1);
}
}
let maxEdges = 0;
for (const count of edgeCount.values()) {
maxEdges = Math.max(maxEdges, count);
}
return wall.length - maxEdges;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(∑wall[i].length) | 需要遍历所有砖块来计算缝隙位置 |
| 空间复杂度 | O(缝隙总数) | 哈希表存储所有可能的缝隙位置及其出现次数 |