Count of submatrix with sum X

Last Updated : 26 Feb, 2026

Given a matrix mat[][] of size n*m and an integer x, Find the number of sub-squares in the matrix with sum of elements equal to x.
Examples: 

Input: mat[][] = [[2, 4, 7, 8, 10], x = 10
[3, 1, 1, 1, 1],
[9, 11, 1, 2, 1],
[12, -17, 1, 1, 1]]
Output:
Explanation:  The sub-squares are colored in the matrix.

22

Input: mat[][] = [[3, 3, 5, 3], x = 1
[2, 2, 2, 6],
[11, 2, 2, 4]] 
Output: 0
Explanation: There are no sub-squares whose sum is 1.

Try It Yourself
redirect icon

[Naive Approach] Generate all possible sub-square matrices

Generate all possible sub-squares and check sum of all the elements of the sub-square equals to x. For each square size, it slides a window over all possible top-left positions in the matrix where a square of that size can fit. At each position, it computes the sum of all elements inside the current square using nested loops. If the computed sum is equal to the target value x, it increments the count.

C++
#include <iostream>
#include <vector>
using namespace std;

int countSquare(vector<vector<int>> &mat, int x) {
    int count = 0 ;
    int n = mat.size() ;          
    int m = mat[0].size() ;   
    
    // Maximum possible size of a square
    int maxSize = min(n, m) ;       

    // Try all possible square sizes
    for (int size = 1; size <= maxSize; size++) {
        
        // Loop through all top-left corners of 
        // squares of this size
        for (int i = 0; i <= n - size; i++) {
            for (int j = 0; j <= m - size; j++) {
                int sum = 0;

                // Compute the sum of the current square
                for (int p = i; p < i + size; p++) {
                    for (int q = j; q < j + size; q++) {
                        sum += mat[p][q];
                    }
                }

                // Check if the sum matches the target value x
                if (sum == x) {
                    count++;
                }
            }
        }
    }
    return count;
}

int main()
{
    vector<vector<int> > mat = {
        {2, 4, 7, 8, 10},
        {3, 1, 1, 1, 1},
        {9, 11, 1, 2, 1},
        {12, -17, 1, 1, 1}
    };

    int x = 10;  

    int res = countSquare(mat, x);
    cout << res << endl;
    return 0;
}
Java
public class GfG {
    public static int countSquare(int[][] mat, int x) {
        int count = 0;
        int n = mat.length;             
        int m = mat[0].length;     
        
        // Largest possible square size
        int maxSize = Math.min(n, m);      

        // Try all square sizes from 1x1 to maxSize x maxSize
        for (int size = 1; size <= maxSize; size++) {
        
            // Slide square of current size across all 
            // valid top-left positions
            for (int i = 0; i <= n - size; i++) {
                for (int j = 0; j <= m - size; j++) {
                    int sum = 0;

                    // Compute sum of the current square submatrix
                    for (int p = i; p < i + size; p++) {
                        for (int q = j; q < j + size; q++) {
                            sum += mat[p][q];
                        }
                    }

                    // If sum matches the target, increment the count
                    if (sum == x) {
                        count++;
                    }
                }
            }
        }

        return count;
    }

    public static void main(String[] args) {
        int[][] mat = {
            {2, 4, 7, 8, 10},
            {3, 1, 1, 1, 1},
            {9, 11, 1, 2, 1},
            {12, -17, 1, 1, 1}
        };

        int x = 10; 

        int res = countSquare(mat, x);
        System.out.println(res);
    }
}
Python
def countSquare(mat, x):
    count = 0
    n = len(mat)             
    m = len(mat[0])
  
    # Largest square size allowed
    maxSize = min(n, m)

    # Try each square size from 1x1 to max_size x max_size
    for size in range(1, maxSize + 1):
        
        # Slide the square over all valid top-left positions
        for i in range(n - size + 1):
            for j in range(m - size + 1):
                total = 0

                # Calculate sum of the current square submatrix
                for p in range(i, i + size):
                    for q in range(j, j + size):
                        total += mat[p][q]

                # If the sum equals the target x, count it
                if total == x:
                    count += 1
    return count

if __name__ == "__main__":
    mat = [
        [2, 4, 7, 8, 10],
        [3, 1, 1, 1, 1],
        [9, 11, 1, 2, 1],
        [12, -17, 1, 1, 1]
    ]
    x = 10 

    res = countSquare(mat, x)
    print(res)
C#
using System;

class GfG {
    static int countSquare(int[,] mat, int x) {
        int count = 0 ;
        int n = mat.GetLength(0) ;              
        int m = mat.GetLength(1) ;           
     
        // Largest square possible
        int maxSize = Math.Min(n, m) ;       

        // Try all square sizes from 1x1 to maxSize x maxSize
        for (int size = 1; size <= maxSize; size++)
        {
            // Loop over all valid top-left corners
            for (int i = 0; i <= n - size; i++)
            {
                for (int j = 0; j <= m - size; j++)
                {
                    int sum = 0 ;

                    // Calculate sum of current square submatrix
                    for (int p = i; p < i + size; p++)
                    {
                        for (int q = j; q < j + size; q++)
                        {
                            sum += mat[p, q];
                        }
                    }

                    // Check if the submatrix sum matches target
                    if (sum == x)
                    {
                        count++;
                    }
                }
            }
        }

        return count;
    }

    static void Main()
    {
        int[,] mat =
        {
            {2, 4, 7, 8, 10},
            {3, 1, 1, 1, 1},
            {9, 11, 1, 2, 1},
            {12, -17, 1, 1, 1}
        };

        int x = 10 ;

        int res = countSquare(mat, x) ;
        Console.WriteLine(res) ;
    }
}
JavaScript
function countSquare(mat, x) {
    let count = 0;
    const n = mat.length;         
    const m = mat[0].length;      

    // Largest square size allowed
    const maxSize = Math.min(n, m);  

    // Try all square sizes from 1 to maxSize
    for (let size = 1; size <= maxSize; size++) {
       
        // Loop over all valid top-left corners 
        // for the current square size
        for (let i = 0; i <= n - size; i++) {
            for (let j = 0; j <= m - size; j++) {
                let sum = 0;

                // Compute the sum of the current square
                for (let p = i; p < i + size; p++) {
                    for (let q = j; q < j + size; q++) {
                        sum += mat[p][q];
                    }
                }

                // If sum matches the target, increment count
                if (sum === x) {
                    count++;
                }
            }
        }
    }

    return count;
}

// Driver Code
const mat = [
    [2, 4, 7, 8, 10],
    [3, 1, 1, 1, 1],
    [9, 11, 1, 2, 1],
    [12, -17, 1, 1, 1]
];

const x = 10;  

const res = countSquare(mat, x);
console.log(res);

Output
3

Time Complexity: O(n2 * m2 * min(n,m)), because for each square size, the code checks all possible positions and sums all elements within each square.
Auxiliary Space: O(1),  since no extra space has been taken.

[Expected Approach] Prefix sum with hashing

Compute prefix sums row-wise to allow quick calculation of horizontal subarray sums. Then, for every pair of columns i and j, reduce the matrix to a 1D array by summing values in each row between columns i and j. For each such 1D array, maintain a running sum and use a hash map to count how many times a particular prefix sum has occurred. Whenever the difference between the current sum and the target is found in the map, increment the result by that frequency.

C++
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

int countSquare(vector<vector<int>>& mat, int x) {
    int res = 0 ;
    int n = mat.size() ;         
    int m = mat[0].size() ;

    // Compute row-wise prefix sum
    vector<vector<int>> rowPrefix = mat;
    for (int i = 0; i < n; i++)
        for (int j = 1; j < m; j++)
            rowPrefix[i][j] += rowPrefix[i][j - 1];

    // Maximum square size possible
    int maxSize = min(n, m);  

    // Try each possible square size
    for (int size = 1; size <= maxSize; size++) {

        // Slide over all column ranges of width = size
        for (int i = 0; i <= m - size; i++) {
            
            // Right column index
            int j = i + size - 1;  

            // Compute column sum for `size` consecutive rows
            int sum = 0;
            
            for (int row = 0; row < size - 1; row++) {
                sum += rowPrefix[row][j] - 
                            (i > 0 ? rowPrefix[row][i - 1] : 0);
            }

            // Now apply sliding window over rows
            for (int row = size - 1; row < n; row++) {
                
                // Add the new row
                sum += rowPrefix[row][j] - 
                            (i > 0 ? rowPrefix[row][i - 1] : 0);

                // Check if the current square has the required sum
                if (sum == x) res++;

                // Remove the top row of the previous window
                sum -= rowPrefix[row - size + 1][j] - 
                        (i > 0 ? rowPrefix[row - size + 1][i - 1] : 0);
            }
        }
    }

    return res;
}

int main() {
    int x = 10;

    vector<vector<int>> mat = {
        {2, 4, 7, 8, 10},
        {3, 1, 1, 1, 1},
        {9, 11, 1, 2, 1},
        {12, -17, 1, 1, 1}
    };

    cout << countSquare(mat, x) << endl;

    return 0;
}
Java
public class GfG {
    public static int countSquare(int[][] mat, int x) {
        int res = 0;
        int n = mat.length;
        int m = mat[0].length;

        // Compute row-wise prefix sum
        int[][] rowPrefix = new int[n][m];
        for (int i = 0; i < n; i++) {
            rowPrefix[i][0] = mat[i][0];
            for (int j = 1; j < m; j++) {
                rowPrefix[i][j] = rowPrefix[i][j - 1] + mat[i][j];
            }
        }

        int maxSize = Math.min(n, m);

        // Try each possible square size
        for (int size = 1; size <= maxSize; size++) {
            for (int i = 0; i <= m - size; i++) {
                int j = i + size - 1;
                int sum = 0;

                for (int row = 0; row < size - 1; row++) {
                    sum += rowPrefix[row][j] - 
                                (i > 0 ? rowPrefix[row][i - 1] : 0);
                }

                for (int row = size - 1; row < n; row++) {
                    sum += rowPrefix[row][j] - 
                                (i > 0 ? rowPrefix[row][i - 1] : 0);

                    if (sum == x) res++;

                    sum -= rowPrefix[row - size + 1][j] - 
                            (i > 0 ? rowPrefix[row - size + 1][i - 1] : 0);
                }
            }
        }

        return res;
    }

    public static void main(String[] args) {
        int x = 10;
        int[][] mat = {
            {2, 4, 7, 8, 10},
            {3, 1, 1, 1, 1},
            {9, 11, 1, 2, 1},
            {12, -17, 1, 1, 1}
        };

        System.out.println(countSquare(mat, x));
    }
}
Python
def countSquare(mat, x):
    res = 0
    n = len(mat)
    m = len(mat[0])

    # Compute row-wise prefix sum
    rowPrefix = [row[:] for row in mat]
    for i in range(n):
        for j in range(1, m):
            rowPrefix[i][j] += rowPrefix[i][j - 1]

    maxSize = min(n, m)

    # Try all possible square sizes
    for size in range(1, maxSize + 1):

        # Try all possible column ranges [i, j] of width 'size'
        for i in range(m - size + 1):
            j = i + size - 1
            total = 0

            # Compute sum for top (size - 1) rows of the square window
            for row in range(size - 1):
                total += rowPrefix[row][j] - \
                            (rowPrefix[row][i - 1] if i > 0 else 0)

            # Slide the square window down row by row
            for row in range(size - 1, n):
                total += rowPrefix[row][j] - \
                            (rowPrefix[row][i - 1] if i > 0 else 0)

                # Check if the current square has sum x
                if total == x:
                    res += 1

                # Remove the top row of the previous window
                total -= rowPrefix[row - size + 1][j] - \
                    (rowPrefix[row - size + 1][i - 1] if i > 0 else 0)

    return res

if __name__ == "__main__":
    mat = [
        [2, 4, 7, 8, 10],
        [3, 1, 1, 1, 1],
        [9, 11, 1, 2, 1],
        [12, -17, 1, 1, 1]
    ]
    
    x = 10
    print(countSquare(mat, x))
C#
using System;
using System.Collections.Generic;

class GfG {
    static int countSquare(int[,] mat, int x) {
        int res = 0;
        int n = mat.GetLength(0);
        int m = mat.GetLength(1);
    
        // Compute row-wise prefix sum
        int[,] rowPrefix = new int[n, m];
        for (int i = 0; i < n; i++) {
            rowPrefix[i, 0] = mat[i, 0];
            for (int j = 1; j < m; j++) {
                rowPrefix[i, j] = rowPrefix[i, j - 1] + mat[i, j];
            }
        }
    
        int maxSize = Math.Min(n, m);
    
        // Try all square sizes
        for (int size = 1; size <= maxSize; size++) {
    
            // Slide square window horizontally
            for (int i = 0; i <= m - size; i++) {
                int j = i + size - 1;
                int sum = 0;
    
                // Add top (size - 1) rows initially
                for (int row = 0; row < size - 1; row++) {
                    sum += rowPrefix[row, j] -
                           (i > 0 ? rowPrefix[row, i - 1] : 0);
                }
    
                // Slide window down vertically
                for (int row = size - 1; row < n; row++) {
                    sum += rowPrefix[row, j] -
                           (i > 0 ? rowPrefix[row, i - 1] : 0);
    
                    if (sum == x) res++;
    
                    // Remove top row of current square window
                    sum -= rowPrefix[row - size + 1, j] -
                           (i > 0 ? rowPrefix[row - size + 1, i - 1] : 0);
                }
            }
        }
    
        return res;
    }

    static void Main() {
        int x = 10;
        int[,] mat = {
        { 2, 4, 7, 8, 10 },
        { 3, 1, 1, 1, 1 },
        { 9, 11, 1, 2, 1 },
        { 12, -17, 1, 1, 1 }};


        Console.WriteLine(countSquare(mat, x));
    }
}
JavaScript
function countSquare(mat, x) {
    let res = 0;
    const n = mat.length;
    const m = mat[0].length;

    // Compute row-wise prefix sum
    const rowPrefix = mat.map(row => row.slice());
    for (let i = 0; i < n; i++) {
        for (let j = 1; j < m; j++) {
            rowPrefix[i][j] += rowPrefix[i][j - 1];
        }
    }

    const maxSize = Math.min(n, m);

    // Try all square sizes
    for (let size = 1; size <= maxSize; size++) {

        // Slide square window horizontally
        for (let i = 0; i <= m - size; i++) {
            let j = i + size - 1;
            let sum = 0;

            // Add top (size - 1) rows initially
            for (let row = 0; row < size - 1; row++) {
                sum += rowPrefix[row][j] -
                       (i > 0 ? rowPrefix[row][i - 1] : 0);
            }

            // Slide the window down vertically
            for (let row = size - 1; row < n; row++) {
                sum += rowPrefix[row][j] -
                       (i > 0 ? rowPrefix[row][i - 1] : 0);

                // Check if current square sum equals target
                if (sum === x) res++;

                // Subtract top row as window slides down
                sum -= rowPrefix[row - size + 1][j] -
                       (i > 0 ? rowPrefix[row - size + 1][i - 1] : 0);
            }
        }
    }

    return res;
}


// Driver Code
const mat = [
    [2, 4, 7, 8, 10],
    [3, 1, 1, 1, 1],
    [9, 11, 1, 2, 1],
    [12, -17, 1, 1, 1]
];

const x = 10;
console.log(countSquare(mat, x));

Output
3

Time Complexity: O(n * m * min(n,m)), because for each possible square size (up to min(n, m)), the code slides a square window of that size across all valid positions in the matrix, doing constant-time work per position.
Auxiliary Space: O(n*m)

Comment