Maximum Sum Square Sub-Matrix of Given Size k

Last Updated : 18 Jul, 2026

Given an n × n grid mat[][] of integers where values can be negative, find the maximum sum among all possible k × k subgrids.

Examples:

Input: k = 3, mat[][] = [[1,2,-1,4],[-8,-3,4,2],[3,8,10,-8],[-4,-1,1,7]]
Output: 20
Explanation:

2056958346

The 3×3 subgrid [[-3,4,2],[8,10,-8],[-1,1,7]] highlighted in red has the maximum sum of 20.

Input: k = 1, mat[][] = [[4]]
Output: 4
Explanation: Only one 1×1 subgrid exists with sum 4.

Try It Yourself
redirect icon

[Naive Approach] Using Brute Force - O(n^4) Time and O(1) Space

Try every possible k×k subgrid by fixing the top-left corner and summing all k×k elements. Track the maximum sum found.

  • For every valid top-left corner (i, j) compute the sum of the k×k subgrid.
  • Update result if current sum is greater than maximum found so far.
C++
#include <bits/stdc++.h>
using namespace std;

int maximumSum(vector<vector<int>> &mat, int k)
{
    int n = mat.size();
    int res = INT_MIN;

    // Try every possible top-left corner of k x k subgrid
    for (int i = 0; i <= n - k; i++)
    {
        for (int j = 0; j <= n - k; j++)
        {
            int sum = 0;

            // Compute sum of k x k subgrid
            for (int r = i; r < i + k; r++)
                for (int c = j; c < j + k; c++)
                    sum += mat[r][c];

            res = max(res, sum);
        }
    }
    return res;
}

int main()
{
    vector<vector<int>> mat = {{1, 2, -1, 4}, {-8, -3, 4, 2}, {3, 8, 10, -8}, {-4, -1, 1, 7}};
    cout << maximumSum(mat, 3) << endl;
    return 0;
}
Java
class GfG {

    static int maximumSum(int[][] mat, int k)
    {
        int n = mat.length;
        int res = Integer.MIN_VALUE;

        // Try every possible top-left corner of k x k
        // subgrid
        for (int i = 0; i <= n - k; i++) {
            for (int j = 0; j <= n - k; j++) {
                int sum = 0;

                // Compute sum of k x k subgrid
                for (int r = i; r < i + k; r++)
                    for (int c = j; c < j + k; c++)
                        sum += mat[r][c];

                res = Math.max(res, sum);
            }
        }
        return res;
    }

    public static void main(String[] args)
    {
        int[][] mat = { { 1, 2, -1, 4 },
                        { -8, -3, 4, 2 },
                        { 3, 8, 10, -8 },
                        { -4, -1, 1, 7 } };
        System.out.println(maximumSum(mat, 3));
    }
}
Python
def maximumSum(mat, k):
    n = len(mat)
    res = float('-inf')

    # Try every possible top-left corner of k x k subgrid
    for i in range(n - k + 1):
        for j in range(n - k + 1):
            total = 0

            # Compute sum of k x k subgrid
            for r in range(i, i + k):
                for c in range(j, j + k):
                    total += mat[r][c]

            res = max(res, total)
    return res


if __name__ == "__main__":
    mat = [[1, 2, -1, 4], [-8, -3, 4, 2], [3, 8, 10, -8], [-4, -1, 1, 7]]
    print(maximumSum(mat, 3))
C#
using System;

class GfG {

    static int maximumSum(int[][] mat, int k)
    {
        int n = mat.Length;
        int res = int.MinValue;

        // Try every possible top-left corner of k x k
        // subgrid
        for (int i = 0; i <= n - k; i++) {
            for (int j = 0; j <= n - k; j++) {
                int sum = 0;

                // Compute sum of k x k subgrid
                for (int r = i; r < i + k; r++)
                    for (int c = j; c < j + k; c++)
                        sum += mat[r][c];

                res = Math.Max(res, sum);
            }
        }
        return res;
    }

    static void Main()
    {
        int[][] mat = { new int[] { 1, 2, -1, 4 },
                        new int[] { -8, -3, 4, 2 },
                        new int[] { 3, 8, 10, -8 },
                        new int[] { -4, -1, 1, 7 } };
        Console.WriteLine(maximumSum(mat, 3));
    }
}
JavaScript
function maximumSum(mat, k)
{
    const n = mat.length;
    let res = -Infinity;

    // Try every possible top-left corner of k x k subgrid
    for (let i = 0; i <= n - k; i++) {
        for (let j = 0; j <= n - k; j++) {
            let sum = 0;

            // Compute sum of k x k subgrid
            for (let r = i; r < i + k; r++)
                for (let c = j; c < j + k; c++)
                    sum += mat[r][c];

            res = Math.max(res, sum);
        }
    }
    return res;
}

// Driver code
const mat = [
    [ 1, 2, -1, 4 ], [ -8, -3, 4, 2 ], [ 3, 8, 10, -8 ],
    [ -4, -1, 1, 7 ]
];
console.log(maximumSum(mat, 3));

Output
20

[Better Approach] Using 2D Prefix Sum - O(n^2) Time and O(n^2) Space

Instead of recomputing the sum of every k×k subgrid from scratch, precompute a 2D prefix sum array. Then any subgrid sum can be computed in O(1) using the inclusion-exclusion formula.

  • Build 2D prefix sum where pre[i][j] = sum of all elements in rectangle from (0,0) to (i-1,j-1).
  • For each valid top-left corner (i,j) compute k×k subgrid sum in O(1) using pre[i+k][j+k] - pre[i][j+k] - pre[i+k][j] + pre[i][j].
  • Track maximum sum.
C++
#include <bits/stdc++.h>
using namespace std;

int maximumSum(vector<vector<int>> &mat, int k)
{
    int n = mat.size();

    // Build 2D prefix sum
    vector<vector<int>> pre(n + 1, vector<int>(n + 1, 0));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            pre[i][j] = mat[i - 1][j - 1] + pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1];

    // Find maximum sum of k x k subgrid
    int res = INT_MIN;
    for (int i = k; i <= n; i++)
        for (int j = k; j <= n; j++)
        {
            int sum = pre[i][j] - pre[i - k][j] - pre[i][j - k] + pre[i - k][j - k];
            res = max(res, sum);
        }
    return res;
}

int main()
{
    vector<vector<int>> mat = {{1, 2, -1, 4}, {-8, -3, 4, 2}, {3, 8, 10, -8}, {-4, -1, 1, 7}};
    cout << maximumSum(mat, 3) << endl;
    return 0;
}
Java
class GfG {

    static int maximumSum(int[][] mat, int k)
    {
        int n = mat.length;

        // Build 2D prefix sum
        int[][] pre = new int[n + 1][n + 1];
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                pre[i][j] = mat[i - 1][j - 1]
                            + pre[i - 1][j] + pre[i][j - 1]
                            - pre[i - 1][j - 1];

        // Find maximum sum of k x k subgrid
        int res = Integer.MIN_VALUE;
        for (int i = k; i <= n; i++)
            for (int j = k; j <= n; j++) {
                int sum = pre[i][j] - pre[i - k][j]
                          - pre[i][j - k]
                          + pre[i - k][j - k];
                res = Math.max(res, sum);
            }
        return res;
    }

    public static void main(String[] args)
    {
        int[][] mat = { { 1, 2, -1, 4 },
                        { -8, -3, 4, 2 },
                        { 3, 8, 10, -8 },
                        { -4, -1, 1, 7 } };
        System.out.println(maximumSum(mat, 3));
    }
}
Python
def maximumSum(mat, k):
    n = len(mat)

    # Build 2D prefix sum
    pre = [[0] * (n + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            pre[i][j] = mat[i - 1][j - 1] + pre[i - 1][j] + \
                pre[i][j - 1] - pre[i - 1][j - 1]

    # Find maximum sum of k x k subgrid
    res = float('-inf')
    for i in range(k, n + 1):
        for j in range(k, n + 1):
            total = pre[i][j] - pre[i - k][j] - \
                pre[i][j - k] + pre[i - k][j - k]
            res = max(res, total)
    return res


if __name__ == "__main__":
    mat = [[1, 2, -1, 4], [-8, -3, 4, 2], [3, 8, 10, -8], [-4, -1, 1, 7]]
    print(maximumSum(mat, 3))
C#
using System;

class GfG {

    static int maximumSum(int[][] mat, int k)
    {
        int n = mat.Length;

        // Build 2D prefix sum
        int[][] pre = new int[n + 1][];
        for (int i = 0; i <= n; i++)
            pre[i] = new int[n + 1];
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                pre[i][j] = mat[i - 1][j - 1]
                            + pre[i - 1][j] + pre[i][j - 1]
                            - pre[i - 1][j - 1];

        // Find maximum sum of k x k subgrid
        int res = int.MinValue;
        for (int i = k; i <= n; i++)
            for (int j = k; j <= n; j++) {
                int sum = pre[i][j] - pre[i - k][j]
                          - pre[i][j - k]
                          + pre[i - k][j - k];
                res = Math.Max(res, sum);
            }
        return res;
    }

    static void Main()
    {
        int[][] mat = { new int[] { 1, 2, -1, 4 },
                        new int[] { -8, -3, 4, 2 },
                        new int[] { 3, 8, 10, -8 },
                        new int[] { -4, -1, 1, 7 } };
        Console.WriteLine(maximumSum(mat, 3));
    }
}
JavaScript
function maximumSum(mat, k)
{
    const n = mat.length;

    // Build 2D prefix sum
    const pre = Array.from({length : n + 1},
                           () => new Array(n + 1).fill(0));
    for (let i = 1; i <= n; i++)
        for (let j = 1; j <= n; j++)
            pre[i][j] = mat[i - 1][j - 1] + pre[i - 1][j]
                        + pre[i][j - 1] - pre[i - 1][j - 1];

    // Find maximum sum of k x k subgrid
    let res = -Infinity;
    for (let i = k; i <= n; i++)
        for (let j = k; j <= n; j++) {
            const sum = pre[i][j] - pre[i - k][j]
                        - pre[i][j - k] + pre[i - k][j - k];
            res = Math.max(res, sum);
        }
    return res;
}

// Driver code
const mat = [
    [ 1, 2, -1, 4 ], [ -8, -3, 4, 2 ], [ 3, 8, 10, -8 ],
    [ -4, -1, 1, 7 ]
];
console.log(maximumSum(mat, 3));

Output
20

[Expected Approach] Using Sliding Window - O(n^2) Time and O(n) Space

Instead of storing a full 2D prefix sum array of size O(n^2), we use a 1D column sum array. For each row we maintain a sliding window of k rows per column. Then we slide a horizontal window of size k over the column sums to get each k×k subgrid sum in O(1).

  • Maintain colSum[j] = sum of k elements in column j ending at current row using a vertical sliding window.
  • Once k rows are in the window slide a horizontal window of size k over colSum to get k×k subgrid sums.
  • Track maximum sum found.
C++
#include <bits/stdc++.h>
using namespace std;

int maximumSum(vector<vector<int>> &mat, int k)
{
    int n = mat.size();

    // 1D column sum array — O(n) space
    vector<int> colSum(n, 0);
    int res = INT_MIN;

    for (int i = 0; i < n; i++)
    {

        // Update column sums with new row entering and old row leaving window
        for (int j = 0; j < n; j++)
        {
            colSum[j] += mat[i][j];
            if (i >= k)
                colSum[j] -= mat[i - k][j];
        }

        // Slide horizontal window of size k over colSum
        if (i >= k - 1)
        {
            int windowSum = 0;
            for (int j = 0; j < n; j++)
            {
                windowSum += colSum[j];
                if (j >= k)
                    windowSum -= colSum[j - k];
                if (j >= k - 1)
                    res = max(res, windowSum);
            }
        }
    }
    return res;
}

int main()
{
    vector<vector<int>> mat = {{1, 2, -1, 4}, {-8, -3, 4, 2}, {3, 8, 10, -8}, {-4, -1, 1, 7}};
    cout << maximumSum(mat, 3) << endl;
    return 0;
}
Java
class GfG {

    static int maximumSum(int[][] mat, int k)
    {
        int n = mat.length;

        // 1D column sum array — O(n) space
        int[] colSum = new int[n];
        int res = Integer.MIN_VALUE;

        for (int i = 0; i < n; i++) {

            // Update column sums with new row entering and
            // old row leaving window
            for (int j = 0; j < n; j++) {
                colSum[j] += mat[i][j];
                if (i >= k)
                    colSum[j] -= mat[i - k][j];
            }

            // Slide horizontal window of size k over colSum
            if (i >= k - 1) {
                int windowSum = 0;
                for (int j = 0; j < n; j++) {
                    windowSum += colSum[j];
                    if (j >= k)
                        windowSum -= colSum[j - k];
                    if (j >= k - 1)
                        res = Math.max(res, windowSum);
                }
            }
        }
        return res;
    }

    public static void main(String[] args)
    {
        int[][] mat = { { 1, 2, -1, 4 },
                        { -8, -3, 4, 2 },
                        { 3, 8, 10, -8 },
                        { -4, -1, 1, 7 } };
        System.out.println(maximumSum(mat, 3));
    }
}
Python
def maximumSum(mat, k):
    n = len(mat)

    # 1D column sum array — O(n) space
    colSum = [0] * n
    res = float('-inf')

    for i in range(n):

        # Update column sums with new row entering and old row leaving window
        for j in range(n):
            colSum[j] += mat[i][j]
            if i >= k:
                colSum[j] -= mat[i - k][j]

        # Slide horizontal window of size k over colSum
        if i >= k - 1:
            windowSum = 0
            for j in range(n):
                windowSum += colSum[j]
                if j >= k:
                    windowSum -= colSum[j - k]
                if j >= k - 1:
                    res = max(res, windowSum)

    return res


if __name__ == "__main__":
    mat = [[1, 2, -1, 4], [-8, -3, 4, 2], [3, 8, 10, -8], [-4, -1, 1, 7]]
    print(maximumSum(mat, 3))
C#
using System;

class GfG {

    static int maximumSum(int[][] mat, int k)
    {
        int n = mat.Length;

        // 1D column sum array — O(n) space
        int[] colSum = new int[n];
        int res = int.MinValue;

        for (int i = 0; i < n; i++) {

            // Update column sums with new row entering and
            // old row leaving window
            for (int j = 0; j < n; j++) {
                colSum[j] += mat[i][j];
                if (i >= k)
                    colSum[j] -= mat[i - k][j];
            }

            // Slide horizontal window of size k over colSum
            if (i >= k - 1) {
                int windowSum = 0;
                for (int j = 0; j < n; j++) {
                    windowSum += colSum[j];
                    if (j >= k)
                        windowSum -= colSum[j - k];
                    if (j >= k - 1)
                        res = Math.Max(res, windowSum);
                }
            }
        }
        return res;
    }

    static void Main()
    {
        int[][] mat = { new int[] { 1, 2, -1, 4 },
                        new int[] { -8, -3, 4, 2 },
                        new int[] { 3, 8, 10, -8 },
                        new int[] { -4, -1, 1, 7 } };
        Console.WriteLine(maximumSum(mat, 3));
    }
}
JavaScript
function maximumSum(mat, k)
{
    const n = mat.length;

    // 1D column sum array — O(n) space
    const colSum = new Array(n).fill(0);
    let res = -Infinity;

    for (let i = 0; i < n; i++) {

        // Update column sums with new row entering and old
        // row leaving window
        for (let j = 0; j < n; j++) {
            colSum[j] += mat[i][j];
            if (i >= k)
                colSum[j] -= mat[i - k][j];
        }

        // Slide horizontal window of size k over colSum
        if (i >= k - 1) {
            let windowSum = 0;
            for (let j = 0; j < n; j++) {
                windowSum += colSum[j];
                if (j >= k)
                    windowSum -= colSum[j - k];
                if (j >= k - 1)
                    res = Math.max(res, windowSum);
            }
        }
    }
    return res;
}

// Driver code
const mat = [
    [ 1, 2, -1, 4 ], [ -8, -3, 4, 2 ], [ 3, 8, 10, -8 ],
    [ -4, -1, 1, 7 ]
];
console.log(maximumSum(mat, 3));

Output
20
Comment