Open In App

Count of submatrix with sum X in a given Matrix

Given a matrix of size N x M and an integer X, the task is to find the number of sub-squares in the matrix with sum of elements equal to X.
Examples: 

Input: N = 4, M = 5, X = 10, arr[][]={{2, 4, 3, 2, 10}, {3, 1, 1, 1, 5}, {1, 1, 2, 1, 4}, {2, 1, 1, 1, 3}} 
Output:
Explanation: 
{10}, {{2, 4}, {3, 1}} and {{1, 1, 1}, {1, 2, 1}, {1, 1, 1}} are subsquares with sum 10.
Input: N = 3, M = 4, X = 8, arr[][]={{3, 1, 5, 3}, {2, 2, 2, 6}, {1, 2, 2, 4}} 
Output:
Explanation: 
Sub-squares {{2, 2}, {2, 2}} and {{3, 1}, {2, 2}} have sum 8. 



Naive Approach: 
The simplest approach to solve the problem is to generate all possible sub-squares and check sum of all the elements of the sub-square equals to X.




#include <iostream>
#include <vector>
 
using namespace std;
 
int count_sub_squares(vector<vector<int> > matrix, int x)
{
    int count = 0;
    int n = matrix.size();
    int m = matrix[0].size();
    int max_size = min(n, m);
    for (int size = 1; size <= max_size; size++) {
        for (int i = 0; i <= n - size; i++) {
            for (int j = 0; j <= m - size; j++) {
                int sum = 0;
                for (int p = i; p < i + size; p++) {
                    for (int q = j; q < j + size; q++) {
                        sum += matrix[p][q];
                    }
                }
                if (sum == x) {
                    count++;
                }
            }
        }
    }
    return count;
}
 
int main()
{
    vector<vector<int> > matrix = { { 2, 4, 3, 2, 10 },
        { 3, 1, 1, 1, 5 },
        { 1, 1, 2, 1, 4 },
        { 2, 1, 1, 1, 3 }
    };
    int x = 10;
    int sub_squares = count_sub_squares(matrix, x);
    cout << "Number of sub-squares with sum " << x << " is "
         << sub_squares << endl;
    return 0;
}




import java.util.ArrayList;
import java.util.List;
 
public class SubSquares {
 
    public static int
    countSubSquares(List<List<Integer> > matrix, int x)
    {
        int count = 0;
        int n = matrix.size();
        int m = matrix.get(0).size();
        int max_size = Math.min(n, m);
        for (int size = 1; size <= max_size; size++) {
            for (int i = 0; i <= n - size; i++) {
                for (int j = 0; j <= m - size; j++) {
                    int sum = 0;
                    for (int p = i; p < i + size; p++) {
                        for (int q = j; q < j + size; q++) {
                            sum += matrix.get(p).get(q);
                        }
                    }
                    if (sum == x) {
                        count++;
                    }
                }
            }
        }
        return count;
    }
 
    public static void main(String[] args)
    {
        List<List<Integer> > matrix = new ArrayList<>();
        matrix.add(List.of(2, 4, 3, 2, 10));
        matrix.add(List.of(3, 1, 1, 1, 5));
        matrix.add(List.of(1, 1, 2, 1, 4));
        matrix.add(List.of(2, 1, 1, 1, 3));
        int x = 10;
        int subSquares = countSubSquares(matrix, x);
        System.out.println("Number of sub-squares with sum "
                           + x + " is " + subSquares);
    }
}




def count_sub_squares(matrix, x):
    count = 0
    n = len(matrix)
    m = len(matrix[0])
    max_size = min(n, m)
 
    # Loop over all possible square sizes from 1 to max_size
    for size in range(1, max_size + 1):
        # Loop over all possible starting points (i, j) of the square
        for i in range(n - size + 1):
            for j in range(m - size + 1):
                # Calculate the sum of elements in the current square
                sum_ = 0
                for p in range(i, i + size):
                    for q in range(j, j + size):
                        sum_ += matrix[p][q]
 
                # If the sum of elements in the current square is equal to x, increment count
                if sum_ == x:
                    count += 1
 
    return count
 
def main():
    matrix = [
        [2, 4, 3, 2, 10],
        [3, 1, 1, 1, 5],
        [1, 1, 2, 1, 4],
        [2, 1, 1, 1, 3]
    ]
    x = 10
    sub_squares = count_sub_squares(matrix, x)
    print("Number of sub-squares with sum", x, "is", sub_squares)
 
if __name__ == "__main__":
    main()




using System;
 
class SubSquareCounter
{
    static int CountSubSquares(int[,] matrix, int x)
    {
        int count = 0;
        int n = matrix.GetLength(0);
        int m = matrix.GetLength(1);
        int maxSize = Math.Min(n, m);
 
        // Loop over all possible square sizes from 1 to maxSize
        for (int size = 1; size <= maxSize; size++)
        {
            // Loop over all possible starting points (i, j) of the square
            for (int i = 0; i <= n - size; i++)
            {
                for (int j = 0; j <= m - size; j++)
                {
                    // Calculate the sum of elements in the current square
                    int sum = 0;
                    for (int p = i; p < i + size; p++)
                    {
                        for (int q = j; q < j + size; q++)
                        {
                            sum += matrix[p, q];
                        }
                    }
 
                    // If the sum of elements in the current square is equal to x, increment count
                    if (sum == x)
                    {
                        count++;
                    }
                }
            }
        }
        return count;
    }
 
    static void Main()
    {
        int[,] matrix = new int[,]
        {
            { 2, 4, 3, 2, 10 },
            { 3, 1, 1, 1, 5 },
            { 1, 1, 2, 1, 4 },
            { 2, 1, 1, 1, 3 }
        };
        int x = 10;
        int subSquares = CountSubSquares(matrix, x);
        Console.WriteLine("Number of sub-squares with sum " + x + " is " + subSquares);
    }
}




// Function to count the number of sub-squares in a matrix with a given sum x
function countSubSquares(matrix, x) {
  let count = 0; // Initialize count to store the number of sub-squares
  const n = matrix.length; // Number of rows in the matrix
  const m = matrix[0].length; // Number of columns in the matrix
  const maxSize = Math.min(n, m); // Maximum size of sub-square possible
 
  // Iterate through possible sizes of sub-squares
  for (let size = 1; size <= maxSize; size++) {
    // Iterate through possible starting rows of sub-squares
    for (let i = 0; i <= n - size; i++) {
      // Iterate through possible starting columns of sub-squares
      for (let j = 0; j <= m - size; j++) {
        let sum = 0; // Initialize sum to store the sum of elements in a sub-square
 
        // Calculate sum of elements in the current sub-square
        for (let p = i; p < i + size; p++) {
          for (let q = j; q < j + size; q++) {
            sum += matrix[p][q];
          }
        }
 
        // If the sum of the sub-square equals x, increment the count
        if (sum === x) {
          count++;
        }
      }
    }
  }
 
  return count; // Return the count of sub-squares with sum equal to x
}
 
// Test matrix
const matrix = [
  [2, 4, 3, 2, 10],
  [3, 1, 1, 1, 5],
  [1, 1, 2, 1, 4],
  [2, 1, 1, 1, 3]
];
const x = 10; // Target sum
 
// Count the number of sub-squares with sum x in the matrix
const subSquares = countSubSquares(matrix, x);
 
// Display the result
console.log(`Number of sub-squares with sum ${x} is ${subSquares}`);

Output

Number of sub-squares with sum 10 is 3





Time Complexity: O(N2 * M2*min(N,M)) 
Auxiliary Space: O(1),  since no extra space has been taken.
 

Efficient Approach: To optimize the above naive approach the sum of all the element of all the matrix till each cell has to be made. Below are the steps:

Below is the implementation of the above approach:




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Size of a column
#define m 5
 
// Function to find the count of submatrix
// whose sum is X
int countSubsquare(int arr[][m],
                   int n, int X)
{
    int dp[n + 1][m + 1];
 
    memset(dp, 0, sizeof(dp));
 
    // Copying arr to dp and making
    // it indexed 1
    for (int i = 0; i < n; i++) {
 
        for (int j = 0; j < m; j++) {
 
            dp[i + 1][j + 1] = arr[i][j];
        }
    }
 
    // Precalculate and store the sum
    // of all rectangles with upper
    // left corner at (0, 0);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
 
            // Calculating sum in
            // a 2d grid
            dp[i][j] += dp[i - 1][j]
                        + dp[i][j - 1]
                        - dp[i - 1][j - 1];
        }
    }
 
    // Stores the answer
    int cnt = 0;
 
    for (int i = 1; i <= n; i++) {
 
        for (int j = 1; j <= m; j++) {
 
            // Fix upper left corner
            // at {i, j} and perform
            // binary search on all
            // such possible squares
 
            // Minimum length of square
            int lo = 1;
 
            // Maximum length of square
            int hi = min(n - i, m - j) + 1;
 
            // Flag to set if sub-square
            // with sum X is found
            bool found = false;
 
            while (lo <= hi) {
                int mid = (lo + hi) / 2;
 
                // Calculate lower
                // right index if upper
                // right corner is at {i, j}
                int ni = i + mid - 1;
                int nj = j + mid - 1;
 
                // Calculate the sum of
                // elements in the submatrix
                // with upper left column
                // {i, j} and lower right
                // column at {ni, nj};
                int sum = dp[ni][nj]
                          - dp[ni][j - 1]
                          - dp[i - 1][nj]
                          + dp[i - 1][j - 1];
 
                if (sum >= X) {
 
                    // If sum X is found
                    if (sum == X) {
                        found = true;
                    }
 
                    hi = mid - 1;
 
                    // If sum > X, then size of
                    // the square with sum X
                    // must be less than mid
                }
                else {
 
                    // If sum < X, then size of
                    // the square with sum X
                    // must be greater than mid
                    lo = mid + 1;
                }
            }
 
            // If found, increment
            // count by 1;
            if (found == true) {
                cnt++;
            }
        }
    }
    return cnt;
}
 
// Driver Code
int main()
{
    int N = 4, X = 10;
 
    // Given Matrix arr[][]
    int arr[N][m] = { { 2, 4, 3, 2, 10 },
                      { 3, 1, 1, 1, 5 },
                      { 1, 1, 2, 1, 4 },
                      { 2, 1, 1, 1, 3 } };
 
    // Function Call
    cout << countSubsquare(arr, N, X)
         << endl;
 
    return 0;
}




// Java program for the above approach
import java.util.*;
class GFG{
 
// Size of a column
static final int m = 5;
 
// Function to find the count of submatrix
// whose sum is X
static int countSubsquare(int arr[][],
                          int n, int X)
{
    int [][]dp = new int[n + 1][m + 1];
 
    // Copying arr to dp and making
    // it indexed 1
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            dp[i + 1][j + 1] = arr[i][j];
        }
    }
 
    // Precalculate and store the sum
    // of all rectangles with upper
    // left corner at (0, 0);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
 
            // Calculating sum in
            // a 2d grid
            dp[i][j] += dp[i - 1][j] +
                          dp[i][j - 1] -
                          dp[i - 1][j - 1];
        }
    }
 
    // Stores the answer
    int cnt = 0;
 
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
 
            // Fix upper left corner
            // at {i, j} and perform
            // binary search on all
            // such possible squares
 
            // Minimum length of square
            int lo = 1;
 
            // Maximum length of square
            int hi = Math.min(n - i, m - j) + 1;
 
            // Flag to set if sub-square
            // with sum X is found
            boolean found = false;
 
            while (lo <= hi)
            {
                int mid = (lo + hi) / 2;
 
                // Calculate lower
                // right index if upper
                // right corner is at {i, j}
                int ni = i + mid - 1;
                int nj = j + mid - 1;
 
                // Calculate the sum of
                // elements in the submatrix
                // with upper left column
                // {i, j} and lower right
                // column at {ni, nj};
                int sum = dp[ni][nj] -
                            dp[ni][j - 1] -
                          dp[i - 1][nj] +
                          dp[i - 1][j - 1];
 
                if (sum >= X)
                {
 
                    // If sum X is found
                    if (sum == X)
                    {
                        found = true;
                    }
 
                    hi = mid - 1;
 
                    // If sum > X, then size of
                    // the square with sum X
                    // must be less than mid
                }
                else
                {
 
                    // If sum < X, then size of
                    // the square with sum X
                    // must be greater than mid
                    lo = mid + 1;
                }
            }
 
            // If found, increment
            // count by 1;
            if (found == true)
            {
                cnt++;
            }
        }
    }
    return cnt;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 4, X = 10;
 
    // Given Matrix arr[][]
    int arr[][] = { { 2, 4, 3, 2, 10 },
                    { 3, 1, 1, 1, 5 },
                    { 1, 1, 2, 1, 4 },
                    { 2, 1, 1, 1, 3 } };
 
    // Function Call
    System.out.print(countSubsquare(arr, N, X) + "\n");
}
}
 
// This code is contributed by sapnasingh4991




# Python3 program for the above approach
 
# Size of a column
m = 5
 
# Function to find the count of
# submatrix whose sum is X
def countSubsquare(arr, n, X):
     
    dp = [[ 0 for x in range(m + 1)]
              for y in range(n + 1)]
 
    # Copying arr to dp and making
    # it indexed 1
    for i in range(n):
        for j in range(m):
            dp[i + 1][j + 1] = arr[i][j]
 
    # Precalculate and store the sum
    # of all rectangles with upper
    # left corner at (0, 0);
    for i in range(1, n + 1):
        for j in range(1, m + 1):
             
            # Calculating sum in
            # a 2d grid
            dp[i][j] += (dp[i - 1][j] +
                         dp[i][j - 1] -
                         dp[i - 1][j - 1])
 
    # Stores the answer
    cnt = 0
 
    for i in range(1, n + 1):
        for j in range(1, m + 1):
             
            # Fix upper left corner
            # at {i, j} and perform
            # binary search on all
            # such possible squares
 
            # Minimum length of square
            lo = 1
 
            # Maximum length of square
            hi = min(n - i, m - j) + 1
 
            # Flag to set if sub-square
            # with sum X is found
            found = False
 
            while (lo <= hi):
                mid = (lo + hi) // 2
 
                # Calculate lower right
                # index if upper right
                # corner is at {i, j}
                ni = i + mid - 1
                nj = j + mid - 1
 
                # Calculate the sum of
                # elements in the submatrix
                # with upper left column
                # {i, j} and lower right
                # column at {ni, nj};
                sum = (dp[ni][nj] -
                       dp[ni][j - 1] -
                       dp[i - 1][nj] +
                       dp[i - 1][j - 1])
 
                if (sum >= X):
                     
                    # If sum X is found
                    if (sum == X):
                        found = True
 
                    hi = mid - 1
 
                    # If sum > X, then size of
                    # the square with sum X
                    # must be less than mid
                else:
 
                    # If sum < X, then size of
                    # the square with sum X
                    # must be greater than mid
                    lo = mid + 1
 
            # If found, increment
            # count by 1;
            if (found == True):
                cnt += 1
    return cnt
 
# Driver Code
if __name__ =="__main__":
 
    N, X = 4, 10
 
    # Given matrix arr[][]
    arr = [ [ 2, 4, 3, 2, 10 ],
            [ 3, 1, 1, 1, 5 ],
            [ 1, 1, 2, 1, 4 ],
            [ 2, 1, 1, 1, 3 ] ]
 
    # Function call
    print(countSubsquare(arr, N, X))
 
# This code is contributed by chitranayal




// C# program for the above approach
using System;
 
class GFG{
 
// Size of a column
static readonly int m = 5;
 
// Function to find the count of submatrix
// whose sum is X
static int countSubsquare(int [,]arr,
                          int n, int X)
{
    int [,]dp = new int[n + 1, m + 1];
 
    // Copying arr to dp and making
    // it indexed 1
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            dp[i + 1, j + 1] = arr[i, j];
        }
    }
 
    // Precalculate and store the sum
    // of all rectangles with upper
    // left corner at (0, 0);
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
 
            // Calculating sum in
            // a 2d grid
            dp[i, j] += dp[i - 1, j] +
                        dp[i, j - 1] -
                        dp[i - 1, j - 1];
        }
    }
 
    // Stores the answer
    int cnt = 0;
 
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
 
            // Fix upper left corner
            // at {i, j} and perform
            // binary search on all
            // such possible squares
 
            // Minimum length of square
            int lo = 1;
 
            // Maximum length of square
            int hi = Math.Min(n - i, m - j) + 1;
 
            // Flag to set if sub-square
            // with sum X is found
            bool found = false;
 
            while (lo <= hi)
            {
                int mid = (lo + hi) / 2;
 
                // Calculate lower
                // right index if upper
                // right corner is at {i, j}
                int ni = i + mid - 1;
                int nj = j + mid - 1;
 
                // Calculate the sum of
                // elements in the submatrix
                // with upper left column
                // {i, j} and lower right
                // column at {ni, nj};
                int sum = dp[ni, nj] -
                          dp[ni, j - 1] -
                          dp[i - 1, nj] +
                          dp[i - 1, j - 1];
 
                if (sum >= X)
                {
 
                    // If sum X is found
                    if (sum == X)
                    {
                        found = true;
                    }
 
                    hi = mid - 1;
 
                    // If sum > X, then size of
                    // the square with sum X
                    // must be less than mid
                }
                else
                {
 
                    // If sum < X, then size of
                    // the square with sum X
                    // must be greater than mid
                    lo = mid + 1;
                }
            }
 
            // If found, increment
            // count by 1;
            if (found == true)
            {
                cnt++;
            }
        }
    }
    return cnt;
}
 
// Driver Code
public static void Main(String[] args)
{
    int N = 4, X = 10;
 
    // Given Matrix [,]arr
    int [,]arr = { { 2, 4, 3, 2, 10 },
                   { 3, 1, 1, 1, 5 },
                   { 1, 1, 2, 1, 4 },
                   { 2, 1, 1, 1, 3 } };
 
    // Function call
    Console.Write(countSubsquare(arr, N, X) + "\n");
}
}
 
// This code is contributed by amal kumar choubey




<script>
 
// Javascript program for the above approach
 
    // Size of a column
     var m = 5;
 
    // Function to find the count of submatrix
    // whose sum is X
    function countSubsquare(arr , n , X) {
        var dp = Array(n + 1);
        for(var i =0;i<n+1;i++)
        dp[i] = Array(m + 1).fill(0);
 
        // Copying arr to dp and making
        // it indexed 1
        for (i = 0; i < n; i++) {
            for (j = 0; j < m; j++) {
                dp[i + 1][j + 1] = arr[i][j];
            }
        }
 
        // Precalculate and store the sum
        // of all rectangles with upper
        // left corner at (0, 0);
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= m; j++) {
 
                // Calculating sum in
                // a 2d grid
                dp[i][j] += dp[i - 1][j] +
                dp[i][j - 1] - dp[i - 1][j - 1];
            }
        }
 
        // Stores the answer
        var cnt = 0;
 
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= m; j++) {
 
                // Fix upper left corner
                // at {i, j} and perform
                // binary search on all
                // such possible squares
 
                // Minimum length of square
                var lo = 1;
 
                // Maximum length of square
                var hi = Math.min(n - i, m - j) + 1;
 
                // Flag to set if sub-square
                // with sum X is found
                var found = false;
 
                while (lo <= hi) {
                    var mid = parseInt((lo + hi) / 2);
 
                    // Calculate lower
                    // right index if upper
                    // right corner is at {i, j}
                    var ni = i + mid - 1;
                    var nj = j + mid - 1;
 
                    // Calculate the sum of
                    // elements in the submatrix
                    // with upper left column
                    // {i, j} and lower right
                    // column at {ni, nj];
                    var sum = dp[ni][nj] - dp[ni][j - 1] -
                    dp[i - 1][nj] + dp[i - 1][j - 1];
 
                    if (sum >= X) {
 
                        // If sum X is found
                        if (sum == X) {
                            found = true;
                        }
 
                        hi = mid - 1;
 
                        // If sum > X, then size of
                        // the square with sum X
                        // must be less than mid
                    } else {
 
                        // If sum < X, then size of
                        // the square with sum X
                        // must be greater than mid
                        lo = mid + 1;
                    }
                }
 
                // If found, increment
                // count by 1;
                if (found == true) {
                    cnt++;
                }
            }
        }
        return cnt;
    }
 
    // Driver Code
     
        var N = 4, X = 10;
 
        // Given Matrix arr
        var arr = [ [ 2, 4, 3, 2, 10 ],
                    [ 3, 1, 1, 1, 5 ],
                    [ 1, 1, 2, 1, 4 ],
                    [ 2, 1, 1, 1, 3 ] ];
 
        // Function Call
        document.write(countSubsquare(arr, N, X) + "<br/>");
 
// This code contributed by umadevi9616
 
</script>

Output
3





Time Complexity: O(N * M * log(max(N, M))) 
Auxiliary Space: O(N * M) since n*m space is being used for populating the 2-d array dp.
 


Article Tags :