Largest Sub-Matrix Sum
{ {1, -2, -1, 4},
{1, -1, 1, 1},
{0, -1, -1, 1},
{0, 0, 1, 1} }
the largest submatrix sum is (-1) + 4 + 1 + 1 + (-1) + 1 + 1 + 1 = 7.Basic Idea:

{ {1, -2, -1, 4},
{1, -1, 1, 1},
{0, -1, -1, 1},
{0, 0, 1, 1} }
the largest submatrix sum is (-1) + 4 + 1 + 1 + (-1) + 1 + 1 + 1 = 7.
public class Solution {
public int largest(int[][] matrix) {
int R = matrix.length, C = matrix[0].length;
// 先获取 2D prefix sum, sums[i][j] 表示从 [0,0] 到 [i,j] submatrix 的和
int[][] sums = new int[R][C];
for (int r = 0; r < R; ++r) {
for (int c = 0; c < C; ++c) {
if (c == 0) {
if (r == 0) { // 左上角
sums[r][c] = matrix[r][c];
} else { // 第一行
sums[r][c] = matrix[r][c] + sums[r - 1][c];
}
} else {
if (r == 0) { // 第一列
sums[r][c] = matrix[r][c] + sums[r][c - 1];
} else { // 右下方普通部分
sums[r][c] = matrix[r][c] + sums[r][c - 1] - sums[r - 1][c - 1] + sums[r - 1][c];
}
}
}
}
// 四重 for loop 遍历所有 submatrix
int globalMaxSum = Integer.MIN_VALUE;
for (int r = 0; r < R; ++r) {
for (int c = 0; c < C; ++c) {
// 对每个 upper left corner point, 循环遍历其开始的submatrix
for (int i = r; i < R; ++i) {
for (int j = c; j < C; ++j) {
int currMatrixSum = sums[i][j];
if (r > 0) currMatrixSum -= sums[r - 1][j];
if (c > 0) currMatrixSum -= sums[i][c - 1];
if (r > 0 && c > 0) currMatrixSum += sums[r - 1][c - 1];
globalMaxSum = Math.max(globalMaxSum, currMatrixSum);
}
}
}
}
return globalMaxSum;
}
}public class Solution {
public int largest(int[][] matrix) {
int R = matrix.length, C = matrix[0].length;
// 先求每行的 prefix sum
int[][] sums = new int[R][C];
for (int r = 0; r < R; ++r) {
for (int c = 0; c < C; ++c) {
if (c == 0) {
sums[r][c] = matrix[r][c];
} else {
sums[r][c] = matrix[r][c] + sums[r][c - 1];
}
}
}
// 遍历每一对左右边界,在边界内考虑不同上下边界求最大和submatrix,Kadane 算法
int globalMaxSum = Integer.MIN_VALUE;
for (int left = 0; left < C; ++left) {
for (int right = left; right < C; ++right) {
int currSum = 0; // 当前左右边界间,某上下边界决定的submatrix的sum
for (int r = 0; r < R; ++r) {
int currRowSum = sums[r][right] - sums[r][left] + matrix[r][left];
if (currSum < 0) {
currSum = currRowSum;
} else {
currSum += currRowSum;
}
globalMaxSum = Math.max(globalMaxSum, currSum);
}
}
}
return globalMaxSum;
}
}