题目描述
给定一个初始元素全部为 0,大小为 m*n 的矩阵 M 以及在 M 上的一系列更新操作。
操作用二维数组表示,其中的每个操作用一个含有两个正整数 a 和 b 的数组表示,含义是将所有符合 0 <= i < a 以及 0 <= j < b 的元素 M[i][j] 的值都增加 1。
在执行给定的一系列操作后,你需要返回矩阵中含有最大整数的元素个数。
示例 1:
输入:
m = 3, n = 3
operations = [[2,2],[3,3]]
输出: 4
解释:
初始状态, M =
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
执行完操作 [2,2] 后, M =
[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]]
执行完操作 [3,3] 后, M =
[[2, 2, 1],
[2, 2, 1],
[1, 1, 1]]
M 中最大的整数是 2, 而且 M 中有4个值为2的元素。因此返回 4。
注意:
- m 和 n 的范围是 [1,40000]。
- a 的范围是 [1,m],b 的范围是 [1,n]。
- 操作数目不超过 10000。
一、我的最初解法
1. 思路
(1)对该矩阵初始化;
(2)依据操作数组,为矩阵中符合条件的元素执行加一操作;
(3)遍历矩阵中的元素,找出最大元素的个数,返回它。
2. 代码
class Solution {
public int maxCount(int m, int n, int[][] ops) {
int A[] = new int[m*n];
int max_size = 0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
A[i*m+j]=0;
for(int i=0;i<ops.length;i++){
add(A,ops[i][0],ops[i][1]);
}
for(int i=ops.length;i>0;i--){
max_size = 0;
for(int j=0;j<m*n;j++){
if(A[j]==i)
max_size++;
}
if(max_size>0)
return max_size;
}
return m*n;
}
public void add(int arr[], int row, int col){
for(int i = 0; i<row; i++){
for(int j = 0; j<col; j++){
arr[i*row+j]+=1;
}
}
}
}
3. 缺点
这花费的时间和内存都挺大的,在LeetCode官网提交的时候就显示超出了内存限制。
二、我的最终解法
之后经过分析,发现矩阵的大小与本题答案无关,具体如下:
1.思路
分析题目,可以发现,这道题的答案与矩阵无关,只需分析操作数组ops即可。
- 操作数组是一个多行2列的二维数组
- 找出其第一列所有元素的最小值row
- 找出其第二列所有元素的最小值col
- 返回row*col,即为所求
为什么可以这样呢?
题目要求返回矩阵中含有最大整数的元素个数,经分析,可以知道最大整数就等于操作数组的长度(也就是ops的行数)。
ops的每一行都会操作一部分元素,作为一次操作。如下图所示:
- 黑色矩形框代表矩阵,红色、橙色、黄色矩形框代表ops数组操作的元素范围;
- 这三次操作共同影响的范围为灰色区域,这个灰色区域内的元素也就是执行“加一”操作最多的那部分元素;
- 灰色区域的面积的大小也就是题目所求——“矩阵中含有最大整数的元素个数”。而灰色区域的面积就是ops数组中第一列所有元素的最小值与第二列所有元素的最小值的乘积、
2.完整代码
class Solution {
public int maxCount(int m, int n, int[][] ops) {
int row=m;
int col=n;
for(int i=0;i<ops.length;i++){
if(ops[i][0]<row)row = ops[i][0];
if(ops[i][1]<col)col = ops[i][1];
}
return row*col;
}
}
总结
拿到题目要先分析,不要盲目开始做!