Count number of square sub matrices of given matrix whose sum of all cells is equal to S | Set 2
Given a matrix, arr[][] of dimensions M*N, and an integer S, the task is to print the count of the number of subsquares of the matrix, whose sum is equal to S.
Examples:
Input: M = 4, N = 5, S = 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:
Sub-squares {10}, {{2, 4}, {3, 1}} and {{1, 1, 1}, {1, 2, 1}, {1, 1, 1}} have sums equal to 10.
Input: M = 3, N = 4, S = 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 sums equal to 8.
Naive Approach: The simplest approach to solve the problem is to generate all possible subsquares and check sum of all the elements of the sub-square equals to S.
Time Complexity: O(N3 * M3)
Auxiliary Space: O(1)
Alternate Approach: The above approach can be optimized by finding the prefix sum of a Matrix which results in the constant time calculation of the sum of all elements of the submatrix. Follow the steps below to solve the problem:
- Find the prefix sum of the matrix arr[][] and store it in a 2D vector say dp of dimension (M + 1)*(N + 1).
- Initialize a variable, say count as 0, to store the count of subsquares with sum S.
- Iterate over the range [1, min(N, M)] using a variable x and perform the following operations:
- Iterate over every element of the matrix arr[][] using the variables i and j and perform the following operations:
- If i and j are greater than or equal to x then find the sum of subsquares of dimension x * x with (i, j) as the bottom-right vertex in a variable, say Sum.
- Update the Sum variable as, Sum = dp[i][j] – dp[i – x][j] – dp[i][j – x] + dp[i – x][j – x].
- If the Sum is equal to S, then increment the count by 1.
- Finally, after completing the above steps, print the value in count as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void find_prefixsum( int M, int N, vector<vector< int > >& arr,
vector<vector< int > >& dp)
{
for ( int i = 0; i <= M; i++) {
dp[i][0] = 0;
}
for ( int j = 0; j <= N; j++) {
dp[0][j] = 0;
}
for ( int i = 1; i <= M; i++) {
for ( int j = 1; j <= N; j++) {
dp[i][j] = dp[i][j - 1] + arr[i - 1][j - 1];
}
}
for ( int i = 1; i <= M; i++) {
for ( int j = 1; j <= N; j++) {
dp[i][j] = dp[i][j] + dp[i - 1][j];
}
}
}
int findSubsquares(vector<vector< int > > arr, int M, int N,
int S)
{
vector<vector< int > > dp(M + 1, vector< int >(N + 1));
find_prefixsum(M, N, arr, dp);
int cnt = 0;
for ( int x = 1; x <= min(N, M); x++) {
for ( int i = x; i <= M; i++) {
for ( int j = x; j <= N; j++) {
int sum = dp[i][j] - dp[i - x][j]
- dp[i][j - x] + dp[i - x][j - x];
if (sum == S) {
cnt++;
}
}
}
}
return cnt;
}
int main()
{
int M = 4, N = 5;
vector<vector< int > > arr = { { 2, 4, 3, 2, 10 },
{ 3, 1, 1, 1, 5 },
{ 1, 1, 2, 1, 4 },
{ 2, 1, 1, 1, 3 } };
int S = 10;
cout << findSubsquares(arr, M, N, S);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static void find_prefixsum( int M, int N, int [][] arr, int [][] dp)
{
for ( int i = 0 ; i <= M; i++) {
dp[i][ 0 ] = 0 ;
}
for ( int j = 0 ; j <= N; j++) {
dp[ 0 ][j] = 0 ;
}
for ( int i = 1 ; i <= M; i++) {
for ( int j = 1 ; j <= N; j++) {
dp[i][j] = dp[i][j - 1 ] + arr[i - 1 ][j - 1 ];
}
}
for ( int i = 1 ; i <= M; i++) {
for ( int j = 1 ; j <= N; j++) {
dp[i][j] = dp[i][j] + dp[i - 1 ][j];
}
}
}
static int findSubsquares( int [][] arr, int M, int N, int S)
{
int [][] dp = new int [M + 1 ][N + 1 ];
find_prefixsum(M, N, arr, dp);
int cnt = 0 ;
for ( int x = 1 ; x <= Math.min(N, M); x++) {
for ( int i = x; i <= M; i++) {
for ( int j = x; j <= N; j++) {
int sum = dp[i][j] - dp[i - x][j]
- dp[i][j - x] + dp[i - x][j - x];
if (sum == S) {
cnt++;
}
}
}
}
return cnt;
}
public static void main(String[] args) {
int M = 4 , N = 5 ;
int [][] arr = { { 2 , 4 , 3 , 2 , 10 },
{ 3 , 1 , 1 , 1 , 5 },
{ 1 , 1 , 2 , 1 , 4 },
{ 2 , 1 , 1 , 1 , 3 } };
int S = 10 ;
System.out.println(findSubsquares(arr, M, N, S));
}
}
|
Python3
def find_prefixsum(M, N, arr, dp):
for i in range ( 0 , M + 1 ):
dp[i][ 0 ] = 0
for j in range ( 0 , N + 1 ):
dp[ 0 ][j] = 0
for i in range ( 1 , M + 1 ):
for j in range ( 1 , N + 1 ):
dp[i][j] = dp[i][j - 1 ] + arr[i - 1 ][j - 1 ]
for i in range ( 1 , M + 1 ):
for j in range ( 1 , N + 1 ):
dp[i][j] = dp[i][j] + dp[i - 1 ][j]
def findSubsquares(arr, M, N, S):
dp = [[ 0 for i in range (N + 1 )] for col in range (M + 1 )]
find_prefixsum(M, N, arr, dp)
cnt = 0
for x in range ( 1 , min (N, M)):
for i in range (x, M + 1 ):
for j in range (x, N + 1 ):
sum = dp[i][j] - dp[i - x][j] - dp[i][j - x] + dp[i - x][j - x]
if ( sum = = S):
cnt + = 1
return cnt
M = 4
N = 5
arr = [[ 2 , 4 , 3 , 2 , 10 ],
[ 3 , 1 , 1 , 1 , 5 ],
[ 1 , 1 , 2 , 1 , 4 ],
[ 2 , 1 , 1 , 1 , 3 ]]
S = 10
print (findSubsquares(arr, M, N, S))
|
C#
using System;
class GFG {
static void find_prefixsum( int M, int N, int [, ] arr,
int [, ] dp)
{
for ( int i = 0; i <= M; i++) {
dp[i, 0] = 0;
}
for ( int j = 0; j <= N; j++) {
dp[0, j] = 0;
}
for ( int i = 1; i <= M; i++) {
for ( int j = 1; j <= N; j++) {
dp[i, j] = dp[i, j - 1] + arr[i - 1, j - 1];
}
}
for ( int i = 1; i <= M; i++) {
for ( int j = 1; j <= N; j++) {
dp[i, j] = dp[i, j] + dp[i - 1, j];
}
}
}
static int findSubsquares( int [, ] arr, int M, int N,
int S)
{
int [, ] dp = new int [M + 1, N + 1];
find_prefixsum(M, N, arr, dp);
int cnt = 0;
for ( int x = 1; x <= Math.Min(N, M); x++) {
for ( int i = x; i <= M; i++) {
for ( int j = x; j <= N; j++) {
int sum = dp[i, j] - dp[i - x, j]
- dp[i, j - x]
+ dp[i - x, j - x];
if (sum == S) {
cnt++;
}
}
}
}
return cnt;
}
public static void Main()
{
int M = 4, N = 5;
int [, ] arr = { { 2, 4, 3, 2, 10 },
{ 3, 1, 1, 1, 5 },
{ 1, 1, 2, 1, 4 },
{ 2, 1, 1, 1, 3 } };
int S = 10;
Console.WriteLine(findSubsquares(arr, M, N, S));
}
}
|
Javascript
<script>
function find_prefixsum(M, N, arr, dp)
{
for ( var i = 0; i <= M; i++) {
dp[i][0] = 0;
}
for ( var j = 0; j <= N; j++) {
dp[0][j] = 0;
}
for ( var i = 1; i <= M; i++) {
for ( var j = 1; j <= N; j++) {
dp[i][j] = dp[i][j - 1] + arr[i - 1][j - 1];
}
}
for ( var i = 1; i <= M; i++) {
for ( var j = 1; j <= N; j++) {
dp[i][j] = dp[i][j] + dp[i - 1][j];
}
}
}
function findSubsquares(arr, M, N, S)
{
var dp = Array.from(Array(M+1), ()=>Array(N+1));
find_prefixsum(M, N, arr, dp);
var cnt = 0;
for ( var x = 1; x <= Math.min(N, M); x++) {
for ( var i = x; i <= M; i++) {
for ( var j = x; j <= N; j++) {
var sum = dp[i][j] - dp[i - x][j]
- dp[i][j - x] + dp[i - x][j - x];
if (sum == S) {
cnt++;
}
}
}
}
return cnt;
}
var M = 4, N = 5;
var arr = [ [ 2, 4, 3, 2, 10 ],
[ 3, 1, 1, 1, 5 ],
[ 1, 1, 2, 1, 4 ],
[ 2, 1, 1, 1, 3 ] ];
var S = 10;
document.write( findSubsquares(arr, M, N, S));
</script>
|
Time Complexity: O(M * N * min(M, N))
Auxiliary Space: O(N * M)
Efficient Approach: The above approach can be further optimized using a binary search Algorithm. Refer to the link for the efficient solution [Count of submatrix with sum X in a given Matrix].
Last Updated :
03 Jun, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...