题目
给你一个 m x n 的矩阵 M
和一个操作数组 op
。矩阵初始化时所有的单元格都为 0 。ops[i] = [ai, bi]
意味着当所有的 0 <= x < ai 和 0 <= y < bi 时, M[x][y]
应该加 1。
在 执行完所有操作后 ,计算并返回 矩阵中最大整数的个数 。
示例 1:
输入: m = 3, n = 3,ops = [[2,2],[3,3]]
输出: 4
解释: M 中最大的整数是 2, 而且 M 中有4个值为2的元素。因此返回 4。
示例 2:
输入: m = 3, n = 3, ops = [[2,2],[3,3],[3,3],[3,3],[2,2],[3,3],[3,3],[3,3],[2,2],[3,3],[3,3],[3,3]]
输出: 4
示例 3:
输入: m = 3, n = 3, ops = []
输出: 9
提示:
1 <= m, n <= 4 * 104
0 <= ops.length <= 104
ops[i].length == 2
1 <= ai <= m
1 <= bi <= n
题解
int maxCount(int m, int n, vector<vector<int>>& ops) {
if (ops.empty()) {
// 如果没有操作,则所有元素都是0,最大整数的个数就是矩阵的面积
return m * n;
}
// 初始化最小值为矩阵的维度
int min_a = m, min_b = n;
// 遍历操作数组,找到最小的ai和bi
for (const auto& op : ops) {
min_a = min(min_a, op[0]);
min_b = min(min_b, op[1]);
}
// 最大整数的个数就是左上角(0, 0)到(min_a-1, min_b-1)的矩形区域的面积
return min_a * min_b;
}
算法原理
这段代码的算法原理相对直观,主要涉及到遍历一个二维向量(vector<vector<int>>
)来寻找特定维度(在这个例子中是ai
和bi
)的最小值。这里,我们假设ops
是一个vector<vector<int>>
,其中每个内部vector<int>
都恰好包含两个元素,分别代表ai
和bi
。
- 初始化:首先,将
min_a
和min_b
初始化为矩阵的维度m
和n
。这是一个保守的起始值,因为我们知道实际的ai
和bi
值(即操作的范围)一定不会超过矩阵的维度。然而,在实际操作中,ai
和bi
很可能会远小于m
和n
。 - 遍历操作:然后,代码遍历
ops
容器中的每个操作(即每个内部vector<int>
)。对于每个操作,它检查op[0]
(即ai
)和op[1]
(即bi
)的值,并将它们与当前的min_a
和min_b
进行比较。 - 更新最小值:如果当前操作的
ai
小于min_a
,则更新min_a
为当前ai
的值。同样地,如果当前操作的bi
小于min_b
,则更新min_b
为当前bi
的值。这个过程确保了min_a
和min_b
在遍历结束时分别包含所有操作中ai
和bi
的最小值。 - 计算结果:最后,代码通过计算
min_a * min_b
来得到最终矩阵中最大整数的个数。这是因为所有操作都会覆盖矩阵的左上角区域,直到(min_a-1, min_b-1
)这个位置。由于每个被覆盖的位置的值都会增加(在这个问题中,由于我们只关心最大整数的个数,而不关心具体的值是多少),因此这个矩形区域内的所有元素都将具有相同的最大值(即被覆盖的次数)。