2536. 子矩阵元素加 1
给你一个正整数 n
,表示最初有一个 n x n
、下标从 0 开始的整数矩阵 mat
,矩阵中填满了 0 。
另给你一个二维整数数组 query
。针对每个查询 query[i] = [row1i, col1i, row2i, col2i]
,请你执行下述操作:
- 找出 左上角 为
(row1i, col1i)
且 右下角 为(row2i, col2i)
的子矩阵,将子矩阵中的 每个元素 加1
。也就是给所有满足row1i <= x <= row2i
和col1i <= y <= col2i
的mat[x][y]
加1
。
返回执行完所有操作后得到的矩阵 mat
。
示例 1:
输入:n = 3, queries = [[1,1,2,2],[0,0,1,1]] 输出:[[1,1,0],[1,2,1],[0,1,1]] 解释:上图所展示的分别是:初始矩阵、执行完第一个操作后的矩阵、执行完第二个操作后的矩阵。 - 第一个操作:将左上角为 (1, 1) 且右下角为 (2, 2) 的子矩阵中的每个元素加 1 。 - 第二个操作:将左上角为 (0, 0) 且右下角为 (1, 1) 的子矩阵中的每个元素加 1 。
二维差分,听着比一维差分多一维,但实际上做起来还是套用一维的做法,实际操作和中心思想没有太大变化。
我做的时候将所有的单列看作一个一维数组,如果该数组中有部分被包在目标数组中,则将头加一,尾部后一位减一,得出该数组的差分数组,最后将二维数组竖向求前缀和即可。
public static int[][] rangeAddQueries(int n, int[][] queries) {
int[][] nums = new int[n][n];
for (int[] query:queries){
for (int i=query[1];i<=query[3];i++){
nums[query[0]][i]++;
}
if(query[2]<n-1){
for (int i=query[1];i<=query[3];i++){
nums[query[2]+1][i]--;
}
}
}
for (int i=0;i<n;i++){
for (int j=1;j<n;j++){
nums[j][i]+=nums[j-1][i];
}
}
return nums;
}