Open In App

Count of submatrix with sum X in a given Matrix

Last Updated : 11 Jul, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

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.

[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 countSquares(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 = countSquares(mat, x);
    cout << res << endl;
    return 0;
}
Java
public class GfG {
    public static int countSquares(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 = countSquares(mat, x);
        System.out.println(res);
    }
}
Python
def countSquares(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 = countSquares(mat, x)
    print(res)
C#
using System;

class GfG {
    static int countSquares(int[][] mat, int x) {
        int count = 0 ;
        int n = mat.Length ;              
        int m = mat[0].Length ;           
     
        // 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 = new int[][]
        {
            new int[] {2, 4, 7, 8, 10},
            new int[] {3, 1, 1, 1, 1},
            new int[] {9, 11, 1, 2, 1},
            new int[] {12, -17, 1, 1, 1}
        };

        int x = 10 ;

        int res = countSquares(mat, x) ;
        Console.WriteLine(res) ;
    }
}
JavaScript
function countSquares(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 = countSquares(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)

    for size in range(1, maxSize + 1):
        for i in range(m - size + 1):
            j = i + size - 1
            total = 0

            for row in range(size - 1):
                total += rowPrefix[row][j] - (rowPrefix[row][i - 1] if i > 0 else 0)

            for row in range(size - 1, n):
                total += rowPrefix[row][j] - (rowPrefix[row][i - 1] if i > 0 else 0)

                if total == x:
                    res += 1

                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.Length;
        int m = mat[0].Length;

        int[][] rowPrefix = new int[n][];
        for (int i = 0; i < n; i++) {
            rowPrefix[i] = new int[m];
            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);

        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;
    }

    static void Main() {
        int x = 10;
        int[][] mat = new int[][] {
            new int[] {2, 4, 7, 8, 10},
            new int[] {3, 1, 1, 1, 1},
            new int[] {9, 11, 1, 2, 1},
            new int[] {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);

    for (let size = 1; size <= maxSize; size++) {
        for (let i = 0; i <= m - size; i++) {
            let j = i + size - 1;
            let sum = 0;

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

            for (let 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;
}

// 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)


Similar Reads