Prefix Sum of Matrix (Or 2D Array)
Last Updated :
29 Mar, 2024
Given a matrix (or 2D array) a[][] of integers, find the prefix sum matrix for it. Let prefix sum matrix be psa[][]. The value of psa[i][j] contains the sum of all values which are above it or on the left of it.
Prerequisite: Prefix Sum – 1D
A simple solution is to find psa[i][j] by traversing and adding values from a[0][0] to a[i][j]. Time complexity of this solution is O(R * C * R * C).
An efficient solution is to use previously computed values to compute psa[i][j]. Unlike 1D array prefix sum, this is tricky, here if we simply add psa[i][j-1] and psa[i-1][j], we get sum of elements from a[0][0] to a[i-1][j-1] twice, so we subtract psa[i-1][j-1].
Example :
psa[3][3] = psa[2][3] + psa[3][2] -
psa[2][2] + a[3][3]
= 6 + 6 - 4 + 1
= 9
The general formula:
psa[i][j] = psa[i-1][j] + psa[i][j-1] -
psa[i-1][j-1] + a[i][j]
Corner Cases (First row and first column)
If i = 0 and j = 0
psa[i][j] = a[i][j]
If i = 0 and j > 0
psa[i][j] = psa[i][j-1] + a[i][j]
If i > 0 and j = 0
psa[i][j] = psa[i-1][j] + a[i][j]
Below is the implementation of the above approach
C++
#include <bits/stdc++.h>
using namespace std;
#define R 4
#define C 5
void prefixSum2D( int a[][C])
{
int psa[R][C];
psa[0][0] = a[0][0];
for ( int i = 1; i < C; i++)
psa[0][i] = psa[0][i - 1] + a[0][i];
for ( int i = 1; i < R; i++)
psa[i][0] = psa[i - 1][0] + a[i][0];
for ( int i = 1; i < R; i++) {
for ( int j = 1; j < C; j++)
psa[i][j] = psa[i - 1][j] + psa[i][j - 1]
- psa[i - 1][j - 1] + a[i][j];
}
for ( int i = 0; i < R; i++) {
for ( int j = 0; j < C; j++)
cout << psa[i][j] << " " ;
cout << "\n" ;
}
}
int main()
{
int a[R][C] = { { 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 } };
prefixSum2D(a);
return 0;
}
|
Java
import java.util.*;
class GFG {
public static void prefixSum2D( int a[][])
{
int R = a.length;
int C = a[ 0 ].length;
int psa[][] = new int [R][C];
psa[ 0 ][ 0 ] = a[ 0 ][ 0 ];
for ( int i = 1 ; i < C; i++)
psa[ 0 ][i] = psa[ 0 ][i - 1 ] + a[ 0 ][i];
for ( int i = 1 ; i < R; i++)
psa[i][ 0 ] = psa[i - 1 ][ 0 ] + a[i][ 0 ];
for ( int i = 1 ; i < R; i++)
for ( int j = 1 ; j < C; j++)
psa[i][j] = psa[i - 1 ][j] + psa[i][j - 1 ]
- psa[i - 1 ][j - 1 ] + a[i][j];
for ( int i = 0 ; i < R; i++) {
for ( int j = 0 ; j < C; j++)
System.out.print(psa[i][j] + " " );
System.out.println();
}
}
public static void main(String[] args)
{
int a[][] = { { 1 , 1 , 1 , 1 , 1 },
{ 1 , 1 , 1 , 1 , 1 },
{ 1 , 1 , 1 , 1 , 1 },
{ 1 , 1 , 1 , 1 , 1 } };
prefixSum2D(a);
}
}
|
Python3
R = 4
C = 5
def prefixSum2D(a) :
global C, R
psa = [[ 0 for x in range (C)]
for y in range (R)]
psa[ 0 ][ 0 ] = a[ 0 ][ 0 ]
for i in range ( 1 , C) :
psa[ 0 ][i] = (psa[ 0 ][i - 1 ] +
a[ 0 ][i])
for i in range ( 0 , R) :
psa[i][ 0 ] = (psa[i - 1 ][ 0 ] +
a[i][ 0 ])
for i in range ( 1 , R) :
for j in range ( 1 , C) :
psa[i][j] = (psa[i - 1 ][j] +
psa[i][j - 1 ] -
psa[i - 1 ][j - 1 ] +
a[i][j])
for i in range ( 0 , R) :
for j in range ( 0 , C) :
print (psa[i][j],
end = " " )
print ()
a = [[ 1 , 1 , 1 , 1 , 1 ],
[ 1 , 1 , 1 , 1 , 1 ],
[ 1 , 1 , 1 , 1 , 1 ],
[ 1 , 1 , 1 , 1 , 1 ]]
prefixSum2D(a)
|
C#
using System;
class GFG
{
static void prefixSum2D( int [,]a)
{
int R = a.GetLength(0);
int C = a.GetLength(1);
int [,]psa = new int [R, C];
psa[0, 0] = a[0, 0];
for ( int i = 1; i < C; i++)
psa[0, i] = psa[0, i - 1] +
a[0, i];
for ( int i = 1; i < R; i++)
psa[i, 0] = psa[i - 1, 0] +
a[i, 0];
for ( int i = 1; i < R; i++)
for ( int j = 1; j < C; j++)
psa[i, j] = psa[i - 1, j] +
psa[i, j - 1] -
psa[i - 1, j - 1] +
a[i, j];
for ( int i = 0; i < R; i++)
{
for ( int j = 0; j < C; j++)
Console.Write(psa[i, j] + " " );
Console.WriteLine();
}
}
static void Main()
{
int [,]a = new int [,]{{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1}};
prefixSum2D(a);
}
}
|
PHP
<?php
$R = 4;
$C = 5;
function prefixSum2D( $a )
{
global $C , $R ;
$psa = array ();
$psa [0][0] = $a [0][0];
for ( $i = 1; $i < $C ; $i ++)
$psa [0][ $i ] = $psa [0][ $i - 1] +
$a [0][ $i ];
for ( $i = 0; $i < $R ; $i ++)
$psa [ $i ][0] = $psa [ $i - 1][0] +
$a [ $i ][0];
for ( $i = 1; $i < $R ; $i ++)
{
for ( $j = 1; $j < $C ; $j ++)
$psa [ $i ][ $j ] = $psa [ $i - 1][ $j ] +
$psa [ $i ][ $j - 1] -
$psa [ $i - 1][ $j - 1] +
$a [ $i ][ $j ];
}
for ( $i = 0; $i < $R ; $i ++)
{
for ( $j = 0; $j < $C ; $j ++)
echo ( $psa [ $i ][ $j ]. " " );
echo ( "\n" );
}
}
$a = array ( array ( 1, 1, 1, 1, 1 ),
array ( 1, 1, 1, 1, 1 ),
array ( 1, 1, 1, 1, 1 ),
array ( 1, 1, 1, 1, 1 ));
prefixSum2D( $a );
?>
|
Javascript
<script>
function prefixSum2D(a)
{
let R = a.length;
let C = a[0].length;
let psa = new Array(R);
for (let i = 0; i < R; i++)
{
psa[i] = new Array(C);
for (let j = 0; j < C; j++)
psa[i][j] = 0;
}
psa[0][0] = a[0][0];
for (let i = 1; i < C; i++)
psa[0][i] = psa[0][i - 1] + a[0][i];
for (let i = 1; i < R; i++)
psa[i][0] = psa[i - 1][0] + a[i][0];
for (let i = 1; i < R; i++)
for (let j = 1; j < C; j++)
psa[i][j] = psa[i - 1][j] + psa[i][j - 1]
- psa[i - 1][j - 1] + a[i][j];
for (let i = 0; i < R; i++) {
for (let j = 0; j < C; j++)
document.write(psa[i][j] + " " );
document.write( "<br>" );
}
}
let a=[[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ]];
prefixSum2D(a);
</script>
|
Output
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
Time Complexity: O(R*C)
Auxiliary Space: O(R*C)
Another Efficient solution in which we also use the previously calculated sums in two main steps would be:
- Calculate the vertical prefix sum for each column.
- Calculate the horizontal prefix sum for each row.
Example
// c = the number of columns
// r = the number of rows
// a is the matrix
// calculating the vertical sum for each column in the Matrix
for(column = 0 to column = c-1)
for(row = 1 to row = r-1)
a[row][column] += a[row-1][column];
// calculating the horizontal sum for each row in the Matrix
for(row = 0 to row = r-1)
for(column = 1 to column = c-1)
a[row][column] += a[row][column -1];
Below is the Implementation of the above approach
C++
#include <iostream>
#include <iomanip>
using namespace std;
void prefixSum( int arr[3][3], int n);
void print( int arr[3][3], int n);
int main()
{
int n = 3;
int arr[3][3] = {{10,20,30},
{5, 10, 20},
{2, 4, 6}
};
prefixSum(arr, n);
print(arr, n);
}
void prefixSum( int arr[3][3], int n) {
for ( int j = 0; j < n; j++) {
for ( int i = 1; i < n; i++) {
arr[i][j] += arr[i-1][j];
}
}
for ( int i = 0; i < n; i++) {
for ( int j = 1; j < n; j++) {
arr[i][j] += arr[i][j-1];
}
}
}
void print( int arr[3][3], int n) {
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
cout << setw(3) << left << arr[i][j] << " " ;
}
cout << '\n' ;
}
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
public class GFG {
public static void main(String[] args)
{
int n = 3 ;
int arr[][] = new int [][] { { 10 , 20 , 30 },
{ 5 , 10 , 20 },
{ 2 , 4 , 6 } };
prefixSum(arr, n);
print(arr, n);
}
static void prefixSum( int arr[][], int n)
{
for ( int j = 0 ; j < n; j++) {
for ( int i = 1 ; i < n; i++) {
arr[i][j] += arr[i - 1 ][j];
}
}
for ( int i = 0 ; i < n; i++) {
for ( int j = 1 ; j < n; j++) {
arr[i][j] += arr[i][j - 1 ];
}
}
}
static void print( int arr[][], int n)
{
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
System.out.print(arr[i][j] + " " );
}
System.out.println();
}
}
}
|
Python3
def prefixsum(arr, n):
for j in range (n):
for i in range ( 1 , n):
arr[i][j] + = arr[i - 1 ][j]
for i in range (n):
for j in range ( 1 , n):
arr[i][j] + = arr[i][j - 1 ]
def printarr(arr, n):
for i in range (n):
for j in range (n):
print (arr[i][j], end = " " )
print ()
n = 3
arr = [[ 10 , 20 , 30 ],[ 5 , 10 , 20 ],[ 2 , 4 , 6 ]]
prefixsum(arr,n)
printarr(arr,n)
|
C#
using System;
public class gfg
{
public static void prefixSum( int [,] arr, int n){
for ( int j = 0; j < n; j++) {
for ( int i = 1; i < n; i++) {
arr[i,j] += arr[i-1,j];
}
}
for ( int i = 0; i < n; i++) {
for ( int j = 1; j < n; j++) {
arr[i,j] += arr[i,j-1];
}
}
}
public static void print( int [,] arr, int n){
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
Console.Write( "{0} " ,arr[i,j]);
}
Console.WriteLine();
}
}
public static void Main( string [] args)
{
int n = 3;
int [ , ] arr = new int [3,3] {{10,20,30},
{5, 10, 20},
{2, 4, 6}
} ;
prefixSum(arr, n);
print(arr, n);
}
}
|
Javascript
function prefixSum(arr, n) {
for (let j = 0; j < n; j++) {
for (let i = 1; i < n; i++) {
arr[i][j] += arr[i - 1][j];
}
}
for (let i = 0; i < n; i++) {
for (let j = 1; j < n; j++) {
arr[i][j] += arr[i][j - 1];
}
}
}
function print(arr, n) {
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
console.log(arr[i][j]);
}
}
}
let n = 3;
let arr= [[ 10, 20, 30 ],
[5, 10, 20 ],
[ 2, 4, 6 ]];
prefixSum(arr, n);
print(arr, n);
|
Output
10 30 60
15 45 95
17 51 107
Time Complexity: O(R*C), where R and C are the Rows and Columns of the given matrix respectively.
Auxiliary Space: O(R*C)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...