Problem
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)]
Challenge
O(n3) time.
Note
原理是这样的:
先对矩阵matrix
的每个点到左顶点之间的子矩阵求和,存在新矩阵sum
上。注意,sum[i+1][j+1]
代表的是matrix[0][0]
到matrix[i][j]
的子矩阵求和。如下所示:
Given matrix[m][n]
------------------
[
[1 ,5 ,7],
[3 ,7 ,-8],
[4 ,-8 ,9],
]
Get sum[m+1][n+1]
-----------------
0 0 0 0
0 1 6 13
0 4 16 15
0 8 12 20
然后,我们进行这样的操作,从0开始,确定两行i1
、i2
,再将第k列的sum[i1][k]
和sum[i2][k]
相减,就得到matrix[i1][0]
到matrix[i2][k-1]
的子矩阵(i2-i1行,k列)求和diff
,存入map。还是在这两行,假设计算到第j列,得到了相等的和diff
。说明从i1到i2行,从k到j列的子矩阵求和为0,即相当于两个平行放置的矩形,若左边的值为diff
,左边与右边之和也是diff
,那么右边的值一定为0
。下面是map中存放操作的例子:
diff-j chart
------------
diff j
1 1 i1 = 0, i2 = 1
6 2
13 3
4 1 i1 = 0, i2 = 2
16 2
15 3
8 1 i1 = 0, i2 = 3
12 2
20 3
3 1 i1 = 1, i2 = 2
10 2
2 3
------------------------------
(above res has no same pair in same region)
7 1 i1 = 1, i2 = 3
6 2
7 3 diff-j pair exists in map
res[0][0] = i1 = 1, res[0][1] = map.get(diff) = 1,
res[1][0] = i2 - 1 = 3 - 1 = 2, res[1][1] = j = 2,
so res = [(1, 1), (2, 2)]
Solution
public class Solution {
public int[][] submatrixSum(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
int[][] sum = new int[m+1][n+1];
int[][] res = new int[2][2];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
sum[i+1][j+1] = matrix[i][j] + sum[i][j+1] + sum[i+1][j] - sum[i][j];
}
}
for (int i1 = 0; i1 < m; i1++) {
for (int i2 = i1+1; i2 <= m; i2++) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int j = 0; j <= n; j++) {
int diff = sum[i2][j] - sum[i1][j];
if (map.containsKey(diff)) {
res[0][0] = i1; res[0][1] = map.get(diff);
res[1][0] = i2-1; res[1][1] = j-1;
return res;
}
else map.put(diff, j);
}
}
}
return res;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。