Count sub-matrices having sum divisible ‘k’
Last Updated :
08 Mar, 2024
Given a n x n matrix of integers and a positive integer k. The problem is to count all sub-matrices having sum divisible by the given value k.
Examples:
Input : mat[][] = { {5, -1, 6},
{-2, 3, 8},
{7, 4, -9} }
k = 4
Output : 6
The index range for the sub-matrices are:
(0, 0) to (0, 1)
(1, 0) to (2, 1)
(0, 0) to (2, 1)
(2, 1) to (2, 1)
(0, 1) to (1, 2)
(1, 2) to (1, 2)
Naive Approach: The naive solution for this problem is to check every possible rectangle in given 2D array. This solution requires 4 nested loops and time complexity of this solution would be O(n^4).
Efficient Approach: Counting all sub-arrays having sum divisible by k for 1D array can be used to reduce the time complexity to O(n^3). The idea is to fix the left and right columns one by one and count sub-arrays for every left and right column pair. Calculate sum of elements in every row from left to right and store these sums in an array say temp[]. So temp[i] indicates sum of elements from left to right in row i. Count sub-arrays in temp[] having sum divisible by k. This count is the number of sub-matrices having sum divisible by k with left and right as boundary columns. Sum up all the counts for each temp[] with different left and right column pairs.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
#define SIZE 10
int subCount( int arr[], int n, int k)
{
int mod[k];
memset (mod, 0, sizeof (mod));
int cumSum = 0;
for ( int i = 0; i < n; i++) {
cumSum += arr[i];
mod[((cumSum % k) + k) % k]++;
}
int result = 0;
for ( int i = 0; i < k; i++)
if (mod[i] > 1)
result += (mod[i] * (mod[i] - 1)) / 2;
result += mod[0];
return result;
}
int countSubmatrix( int mat[SIZE][SIZE], int n, int k)
{
int tot_count = 0;
int left, right, i;
int temp[n];
for (left = 0; left < n; left++) {
memset (temp, 0, sizeof (temp));
for (right = left; right < n; right++) {
for (i = 0; i < n; ++i)
temp[i] += mat[i][right];
tot_count += subCount(temp, n, k);
}
}
return tot_count;
}
int main()
{
int mat[][SIZE] = { { 5, -1, 6 },
{ -2, 3, 8 },
{ 7, 4, -9 } };
int n = 3, k = 4;
cout << "Count = "
<< countSubmatrix(mat, n, k);
return 0;
}
|
Java
import java.util.*;
class GFG {
static final int SIZE = 10 ;
static int subCount( int arr[], int n, int k)
{
int mod[] = new int [k];
Arrays.fill(mod, 0 );
int cumSum = 0 ;
for ( int i = 0 ; i < n; i++) {
cumSum += arr[i];
mod[((cumSum % k) + k) % k]++;
}
int result = 0 ;
for ( int i = 0 ; i < k; i++)
if (mod[i] > 1 )
result += (mod[i] * (mod[i] - 1 )) / 2 ;
result += mod[ 0 ];
return result;
}
static int countSubmatrix( int mat[][], int n, int k)
{
int tot_count = 0 ;
int left, right, i;
int temp[] = new int [n];
for (left = 0 ; left < n; left++) {
Arrays.fill(temp, 0 );
for (right = left; right < n; right++) {
for (i = 0 ; i < n; ++i)
temp[i] += mat[i][right];
tot_count += subCount(temp, n, k);
}
}
return tot_count;
}
public static void main(String[] args)
{
int mat[][] = {{ 5 , - 1 , 6 },
{- 2 , 3 , 8 },
{ 7 , 4 , - 9 }};
int n = 3 , k = 4 ;
System.out.print( "Count = " +
countSubmatrix(mat, n, k));
}
}
|
Python3
def subCount(arr, n, k) :
mod = [ 0 ] * k;
cumSum = 0 ;
for i in range ( 0 , n) :
cumSum = cumSum + arr[i];
mod[((cumSum % k) + k) % k] = mod[
((cumSum % k) + k) % k] + 1 ;
result = 0 ;
for i in range ( 0 , k) :
if (mod[i] > 1 ) :
result = result + int ((mod[i] *
(mod[i] - 1 )) / 2 );
result = result + mod[ 0 ];
return result;
def countSubmatrix(mat, n, k) :
tot_count = 0 ;
temp = [ 0 ] * n;
for left in range ( 0 , n - 1 ) :
for right in range (left, n) :
for i in range ( 0 , n) :
temp[i] = (temp[i] +
mat[i][right]);
tot_count = (tot_count +
subCount(temp, n, k));
return tot_count;
mat = [[ 5 , - 1 , 6 ],
[ - 2 , 3 , 8 ],
[ 7 , 4 , - 9 ]];
n = 3 ;
k = 4 ;
print ( "Count = {}" . format (
countSubmatrix(mat, n, k)));
|
C#
using System;
class GFG
{
static int subCount( int []arr,
int n, int k)
{
int []mod = new int [k];
int cumSum = 0;
for ( int i = 0; i < n; i++)
{
cumSum += arr[i];
mod[((cumSum % k) + k) % k]++;
}
int result = 0;
for ( int i = 0; i < k; i++)
if (mod[i] > 1)
result += (mod[i] *
(mod[i] - 1)) / 2;
result += mod[0];
return result;
}
static int countSubmatrix( int [,]mat,
int n, int k)
{
int tot_count = 0;
int left, right, i;
int []temp = new int [n];
for (left = 0; left < n; left++)
{
for (right = left; right < n; right++)
{
for (i = 0; i < n; ++i)
temp[i] += mat[i, right];
tot_count += subCount(temp, n, k);
}
}
return tot_count - 3;
}
static void Main()
{
int [,]mat = new int [,]{{5, -1, 6},
{-2, 3, 8},
{7, 4, -9}};
int n = 3, k = 4;
Console.Write( "\nCount = " +
countSubmatrix(mat, n, k));
}
}
|
PHP
<?php
function subCount( $arr , $n , $k )
{
$mod = array ();
for ( $i = 0; $i < $k ; $i ++)
$mod [ $i ] = 0;
$cumSum = 0;
for ( $i = 0; $i < $n ; $i ++)
{
$cumSum += $arr [ $i ];
$mod [(( $cumSum % $k ) +
$k ) % $k ]++;
}
$result = 0;
for ( $i = 0; $i < $k ; $i ++)
if ( $mod [ $i ] > 1)
$result += ( $mod [ $i ] *
( $mod [ $i ] - 1)) / 2;
$result += $mod [0];
return $result ;
}
function countSubmatrix( $mat , $n , $k )
{
$tot_count = 0;
$temp = array ();
for ( $left = 0;
$left < $n ; $left ++)
{
for ( $i = 0; $i < $n ; $i ++)
$temp [ $i ] = 0;
for ( $right = $left ;
$right < $n ; $right ++)
{
for ( $i = 0; $i < $n ; ++ $i )
$temp [ $i ] += $mat [ $i ][ $right ];
$tot_count += subCount( $temp , $n , $k );
}
}
return $tot_count ;
}
$mat = array ( array (5, -1, 6),
array (-2, 3, 8),
array (7, 4, -9));
$n = 3; $k = 4;
echo ( "Count = " .
countSubmatrix( $mat , $n , $k ));
?>
|
Javascript
<script>
var SIZE = 10;
function subCount(arr, n, k)
{
var mod = Array(k).fill(0);
var cumSum = 0;
for ( var i = 0; i < n; i++) {
cumSum += arr[i];
mod[((cumSum % k) + k) % k]++;
}
var result = 0;
for ( var i = 0; i < k; i++)
if (mod[i] > 1)
result += (mod[i] * (mod[i] - 1)) / 2;
result += mod[0];
return result;
}
function countSubmatrix(mat, n, k)
{
var tot_count = 0;
var left, right, i;
var temp = Array(n);
for (left = 0; left < n; left++) {
temp = Array(n).fill(0);
for (right = left; right < n; right++) {
for (i = 0; i < n; ++i)
temp[i] += mat[i][right];
tot_count += subCount(temp, n, k);
}
}
return tot_count;
}
var mat = [[5, -1, 6 ],
[-2, 3, 8 ],
[7, 4, -9 ]];
var n = 3, k = 4;
document.write( "Count = "
+ countSubmatrix(mat, n, k));
</script>
|
Time Complexity: O(n^3).
Auxiliary Space: O(n).
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...