Count of submatrix with sum X in a given Matrix
Last Updated :
28 Nov, 2023
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: 3
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: 2
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.
C++
#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;
}
Java
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);
}
}
Python3
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()
C#
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);
}
}
JavaScript
// 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}`);
OutputNumber 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:
- Precalculate the sum of all rectangles with its upper left corner at (0, 0) and lower right at (i, j) in O(N * M) computational complexity.
- Now, it can be observed that, for every upper left corner, there can be at most one square with sum X since elements of the matrix are positive.
- Keeping this in mind we can use binary search to check if there exists a square with sum X.
- For every cell (i, j) in the matrix, fix it as the upper left corner of the subsquare. Then, traverse over all possible subsquares with (i, j) as the upper left corner and increase count if sum is equal to X or not.
Below is the implementation of the above approach:
C++
// 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
// 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
# 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#
// 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
JavaScript
<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>
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.
Similar Reads
Count of odd sum Submatrix with odd element count in the Matrix Given a matrix mat[][] of size N x N, the task is to count the number of submatrices with the following properties: The sum of all elements in the submatrix is odd.The number of elements in the submatrix is odd.Examples: Input: mat[][] = {{1, 2, 3}, {7, 5, 9}, {6, 8, 10}}Output: 8Explanation: As her
15 min read
Count submatrices having only 'X' in given Matrix Given a character matrix consisting of O's and X's, find the number of submatrices containing only 'X' and surrounded by 'O' from all sides. Examples: Input:  grid[][] = {{X, O, X}, {O, X, O}, {X, X, X}}Output: 3 Input: grid[][] = { { 'X', 'O', 'X', 'X' }, { 'O', 'O', 'X', 'X' }, { 'X', 'X', 'O', '
13 min read
Sum of all Submatrices of a Given Matrix Given a n * n 2D matrix, the task to find the sum of all the submatrices.Examples: Input : mat[][] = [[1, 1], [1, 1]];Output : 16Explanation: Number of sub-matrices with 1 elements = 4Number of sub-matrices with 2 elements = 4Number of sub-matrices with 3 elements = 0Number of sub-matrices with 4 el
9 min read
Pair with given sum in matrix Given a NxM matrix and a sum S. The task is to check if a pair with given Sum exists in the matrix or not. Examples: Input: mat[N][M] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; sum = 31 Output: YES Input: mat[N][M] = {{1, 2, 3, 4}, {5, 6, 7, 8}}; sum = 150 Output: NO Approach
6 min read
Find Matrix With Given Row and Column Sums Given two arrays rowSum[] and colSum[] of size n and m respectively, the task is to construct a matrix of dimensions n à m such that the sum of matrix elements in every ith row is rowSum[i] and the sum of matrix elements in every jth column is colSum[j].Note: The resultant matrix can have only non-n
15 min read
Find sub-matrix with the given sum Given an N x N matrix and two integers S and K, the task is to find whether there exists a K x K sub-matrix with sum equal to S. Examples: Input: K = 2, S = 14, mat[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 }} Output: Yes 1 2 5 6 is the required 2 x 2 sub-matrix wit
9 min read
Count of Subarrays with sum equals k in given Binary Array Given a binary array arr[] and an integer k, the task is to find the count of non-empty subarrays with a sum equal to k.Examples:Input: arr[] = {1, 0, 1, 1, 0, 1}, k = 2Output: 6Explanation: All valid subarrays are: {1, 0, 1}, {0, 1, 1}, {1, 1}, {1, 0, 1}, {0, 1, 1, 0}, {1, 1, 0}.Input: arr[] = {0,
10 min read
Count elements smaller than or equal to x in a sorted matrix Given a n x n strictly sorted matrix and a value x. The problem is to count the elements smaller than or equal to x in the given matrix. Here strictly sorted matrix means that matrix is sorted in a way such that all elements in a row are sorted in increasing order and for row âiâ, where 1 <= i
14 min read
Submatrix of given size with maximum 1's Given a binary matrix mat[][] and an integer K, the task is to find the submatrix of size K*K such that it contains maximum number of 1's in the matrix. Examples: Input: mat[][] = {{1, 0, 1}, {1, 1, 0}, {1, 0, 0}}, K = 2 Output: 3 Explanation: In the given matrix, there are 4 sub-matrix of order 2*2
15+ min read
Count paths whose sum is not divisible by K in given Matrix Given an integer matrix mat[][] of size M x N and an integer K, the task is to return the number of paths from top-left to bottom-right by moving only right and downwards such that the sum of the elements on the path is not divisible by K. Examples: Input: mat = [[5, 2, 4], [3, 0, 5], [0, 7, 2]], K
12 min read