Given a NxN 2-D matrix, the task to find the sum of all the submatrices.
Examples:
Input : arr[] = {{1, 1},
{1, 1}};
Output : 16
Explanation:
Number of sub-matrices with 1 elements = 4
Number of sub-matrices with 2 elements = 4
Number of sub-matrices with 3 elements = 0
Number of sub-matrices with 4 elements = 1
Since all the entries are 1, the sum becomes
sum = 1 * 4 + 2 * 4 + 3 * 0 + 4 * 1 = 16
Input : arr[] = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}
Output : 500
Simple Solution: A naive solution is to generate all the possible submatrices and sum up all of them.
The time complexity of this approach will be O(n6).
Efficient Solution : For each element of the matrix, let us try to find the number of sub-matrices, the element will lie in.
This can be done in O(1) time. Let us suppose the index of an element be (X, Y) in 0 based indexing, then the number of submatrices (Sx, y) for this element will be given by the formula Sx, y = (X + 1) * (Y + 1) * (N – X) * (N – Y). This formula works, because we just have to choose two different positions on the matrix that will create a submatrix that envelopes the element. Thus, for each element, ‘sum’ can be updated as sum += (Sx, y) * Arrx, y.
Below is the implementation of the above approach:
Here we need to try to solve this question in the Reverse lookup Technique:
1) For a particular element what are the possible submatrices where this element will be included.
2) When we get the number of possible submatrices then we can count the contribution of that particular element by doing ( a[i]* total number of submatrices where this will be included) where a[i] = current element
3) Now Question comes how to find the number of possible submatrices for a particular element.
[[1 2 3]
[4 5 6]
[7 8 9]]
So let’s consider the current element as 5 , so for 5 there are (X+1)*(Y+1) choices where co-ordinates of submatrix starting point can lie,(Top Left)
Similarly, there will be (N-X)*(N-Y) choices where the end co-ordinates of that submatrix can lie (Bottom Right)
Number of choices for Top Left = (X+1)*(Y+1)
Number of choices for Bottom Right = (N-X)*(N-Y)
Total number of choices for the current element to be included in the submatrix will be : (X+1)*(Y+1) * (N-X)*(N-Y)
Contribution of the current element which can be included in all the possible submatrices will be = arr[X][Y] * (X+1)*(Y+1) * (N-X)*(N-Y)
where X and Y are index of the submatrices.
C++
#include <iostream>
#define n 3
using namespace std;
int matrixSum( int arr[][n])
{
int sum = 0;
for ( int i = 0; i < n; i++)
for ( int j = 0; j < n; j++) {
int top_left = (i + 1) * (j + 1);
int bottom_right = (n - i) * (n - j);
sum += (top_left * bottom_right * arr[i][j]);
}
return sum;
}
int main()
{
int arr[][n] = { { 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 } };
cout << matrixSum(arr);
return 0;
}
|
Java
class GFG
{
static final int n = 3 ;
static int matrixSum( int arr[][])
{
int sum = 0 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < n; j++)
{
int top_left = (i + 1 ) * (j + 1 );
int bottom_right = (n - i) * (n - j);
sum += (top_left * bottom_right * arr[i][j]);
}
}
return sum;
}
public static void main(String[] args)
{
int arr[][] = {{ 1 , 1 , 1 },
{ 1 , 1 , 1 },
{ 1 , 1 , 1 }};
System.out.println(matrixSum(arr));
}
}
|
Python3
n = 3
def matrixSum(arr) :
sum = 0 ;
for i in range (n) :
for j in range (n) :
top_left = (i + 1 ) * (j + 1 );
bottom_right = (n - i) * (n - j);
sum + = (top_left * bottom_right *
arr[i][j]);
return sum ;
if __name__ = = "__main__" :
arr = [[ 1 , 1 , 1 ],
[ 1 , 1 , 1 ],
[ 1 , 1 , 1 ]];
print (matrixSum(arr))
|
C#
using System;
class GFG
{
static int n = 3;
static int matrixSum( int [,]arr)
{
int sum = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
int top_left = (i + 1) * (j + 1);
int bottom_right = (n - i) * (n - j);
sum += (top_left * bottom_right * arr[i, j]);
}
}
return sum;
}
public static void Main()
{
int [,]arr = {{1, 1, 1},
{1, 1, 1},
{1, 1, 1}};
Console.WriteLine(matrixSum(arr));
}
}
|
PHP
<?php
function matrixSum( $arr )
{
$n = 3;
$sum = 0;
for ( $i = 0; $i < $n ; $i ++)
for ( $j = 0; $j < $n ; $j ++)
{
$top_left = ( $i + 1) * ( $j + 1);
$bottom_right = ( $n - $i ) * ( $n - $j );
$sum += ( $top_left * $bottom_right *
$arr [ $i ][ $j ]);
}
return $sum ;
}
$arr = array ( array (1, 1, 1),
array (1, 1, 1),
array (1, 1, 1));
echo matrixSum( $arr );
?>
|
Javascript
<script>
let n = 3;
function matrixSum(arr)
{
let sum = 0;
for (let i = 0; i < n; i++)
for (let j = 0; j < n; j++) {
let top_left = (i + 1) * (j + 1);
let bottom_right = (n - i) * (n - j);
sum += (top_left * bottom_right * arr[i][j]);
}
return sum;
}
let arr = [[ 1, 1, 1 ],
[ 1, 1, 1 ],
[ 1, 1, 1 ]] ;
document.write(matrixSum(arr));
</script>
|
Time Complexity: O(n2)
Auxiliary Space: O(1)