Submatrix Sum
Given an integer matrix, find a submatrix where the sum of numbers is zero. Your code should return the coordinate of the left-up and right-down number.
Example
Given matrix
[
[1 ,5 ,7],
[3 ,7 ,-8],
[4 ,-8 ,9],
]
return[(1,1), (2,2)]
分析
subarray sum的matrix变种
presum的计算法:此处是每一列的sum
sumY[i][j] = i-1 < 0 ? 0 : sumY[i-1][j] + matrix[i][j];
矩阵和的计算法:以x,y为终点的方块面积,计算时候外面左边和上面包一层0。
先求每一列的和,然后在此基础上求每一行的和,就是以xy结尾的矩阵和。
sumY[i][j] = i-1 < 0 ? 0 : sumY[i-1][j] + matrix[i][j];
sum[i][j] = sum[i][j-1] + sumY[i-1][j-1];
2.左边+上面-重合部分+当前点matrix[i][j]
sum[i+1][j+1] = matrix[i][j] + sum[i+1][j] + sum[i][j+1] - sum[i][j];
代码说明:预处理得到以0,0为起点,x,y为终点的矩阵和,x轴上设置low,high,然后遍历y轴j,得到以0为起点,j轴为终点的矩形面积。
用Hashmap存储以0轴为起点,y轴为终点,low和high内切的矩形面积。如果下一次再遇到这个面积,说明中间有一段包含的面积是0。
tricky点:结果里起点左边直接用,终点坐标都要-1
答案
注释的部分是另一种矩阵和的做法。
public int[][] submatrixSum(int[][] matrix) {
// Write your code here
if(matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0)
return null;
int n = matrix.length;
int m = matrix[0].length;
int[][] ret = new int[2][2];
int[][] sumY = new int[n][m];
int[][] sum = new int[n+1][m+1];
for(int j = 0; j < m; j++)
{
for(int i = 0; i < n; i++){
sumY[i][j] = i-1 < 0 ? 0 : sumY[i-1][j] + matrix[i][j];
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++){
sum[0][j] = 0;
sum[i][j] = sum[i][j-1] + sumY[i-1][j-1];
}
}
// int n = matrix.length;
// int m = matrix[0].length;
// int[][] ret = new int[2][2];
// // pre-compute: sum[i][j] = sum of submatrix [(0, 0), (i, j)]
// int[][] sum = new int[n+1][m+1];
// for (int j=0; j<=m; ++j) sum[0][j] = 0;
// for (int i=1; i<=n; ++i) sum[i][0] = 0;
// for (int i=0; i<n; ++i) {
// for (int j=0; j<m; ++j)
// sum[i+1][j+1] = matrix[i][j] + sum[i+1][j] + sum[i][j+1] - sum[i][j];
// }
for(int l = 0; l < n; l++)
{
for(int h = l + 1; h <= n; h++){
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int j = 0; j <= m; j++){
int diff = sum[h][j] - sum[l][j];
if(map.containsKey(diff)){
int k = map.get(diff);
ret[0][0] = l;
ret[0][1] = k;
ret[1][0] = h-1;
ret[1][1] = j-1;
}else{
map.put(diff, j);
}
}
}
}
return ret;
}
Last updated
Was this helpful?