题目
给定一个初始元素全部为 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。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-addition-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
想法
看到这道题,先把这道题读懂才行,就是在他给的矩阵opes的范围内 对一个全为0的m*n数组基础上自加1,找到出现的最大数的频次。
我没什么好的方法,就一步步算的,相当于暴力解法:
class Solution {
public int maxCount(int m, int n, int[][] ops) {
int arr[][] = new int[m][n];//初始化 为0 ;
for(int op[]:ops)//遍历的就是ops的一行
{
int a = op[0];
int b = op[1];
for(int i = 0 ; i<a;i++)
{
for(int j = 0 ; j<b;j++)
{
arr[i][j]++;
}
}
}
int count = 0 ;
int max = 0;
for(int arr1[]:arr)
{
for(int num:arr1)
{
if(num>=max)
{
max = Math.max(max,num);
count++;
}
}
}
return count;
}
}
输入几个测试案例是可以通过的,但是m 和 n 的范围是 [1,40000]。提交后 给我测试案例就是
40000
40000
[]
直接超出内存限制了。
所以这题还是得使用巧方法,不能硬来。
每次自加1都是从(0,0)位置来的,那么最大的数字就是重叠的部分,取二者的交集即可,
需要找到最小的a和最小的b相乘就好。
这样就比以上方法简单多了。
class Solution {
public int maxCount(int m, int n, int[][] ops) {
//每次操作都是左上角区域从(0, 0)到(a, b)的矩形,必定重叠,所以找最小的a乘最小的b就行
if(ops.length == 0 )
{
return m*n;
}
int a = Integer.MAX_VALUE;
int b = Integer.MAX_VALUE;
for(int i = 0 ; i <ops.length;i++)
{
a=Math.min(a,ops[i][0]);
b=Math.min(b,ops[i][1]);
}
return a*b;
}
}
总结
这道题自己做的时候还是有点轴,想想应该不能使用暴力,但不会别的了,所以先写出来了,后来看答案,原来这样才是最快的,因为是得到最大数的频次,而不是最大频次的数字,是不一样的,所以有时候需要转换思想才行。