I am trying to figure out how to implement C# code for Kadane's 2D Matrix algorithm. I found a 1D version here:
But I want a 2D version. Basically, given a Matrix N x N of positive and negative numbers, I need to find a submatrix where sum of all elements would be the greatest.
Figured it out. For those who is interested
static void Main(string[] args)
{
int[,] array2D = new int[,]
{
{ 1, 2 },
{ -3, 4 },
{ 5, -6 },
{ -7, -8 }
};
var max = GetMaxMatrix(array2D);
Console.WriteLine(max);
}
public static int GetMaxMatrix(int[,] original)
{
int maxArea = int.MinValue;
int rowCount = original.GetLength(0);
int columnCount = original.GetLength(1);
int[,] matrix = PrecomputeMatrix(original);
for (int row1 = 0; row1 < rowCount; row1++)
{
for (int row2 = row1; row2 < rowCount; row2++)
{
for (int col1 = 0; col1 < columnCount; col1++)
{
for (int col2 = col1; col2 < columnCount; col2++)
{
maxArea = Math.Max(maxArea, ComputeSum(matrix, row1, row2, col1, col2));
}
}
}
}
return maxArea;
}
private static int[,] PrecomputeMatrix(int[,] matrix)
{
var sumMatrix = new int[matrix.GetLength(0), matrix.GetLength(1)];
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
if (i == 0 && j == 0)
{ // first cell
sumMatrix[i, j] = matrix[i, j];
}
else if (j == 0)
{ // cell in first column
sumMatrix[i, j] = sumMatrix[i - 1, j] + matrix[i, j];
}
else if (i == 0)
{ // cell in first row
sumMatrix[i, j] = sumMatrix[i, j - 1] + matrix[i, j];
}
else
{
sumMatrix[i, j] = sumMatrix[i - 1, j] +
sumMatrix[i, j - 1] - sumMatrix[i - 1, j - 1] + matrix[i, j];
}
}
}
return sumMatrix;
}
private static int ComputeSum(int[,] sumMatrix, int i1, int i2, int j1, int j2)
{
if (i1 == 0 && j1 == 0)
{ // starts at row 0, column 0
return sumMatrix[i2, j2];
}
else if (i1 == 0)
{ // start at row 0
return sumMatrix[i2, j2] - sumMatrix[i2, j1 - 1];
}
else if (j1 == 0)
{ // start at column 0
return sumMatrix[i2, j2] - sumMatrix[i1 - 1, j2];
}
else
{
return sumMatrix[i2, j2] - sumMatrix[i2, j1 - 1]
- sumMatrix[i1 - 1, j2] + sumMatrix[i1 - 1, j1 - 1];
}
}