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++
// C++ Program to find prefix sum of 2d array#include <bits/stdc++.h>using namespace std;#define R 4#define C 5// calculating new arrayvoid prefixSum2D(int a[][C]){ int psa[R][C]; psa[0][0] = a[0][0]; // Filling first row and first column 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]; // updating the values in the cells // as per the general formula for (int i = 1; i < R; i++) { for (int j = 1; j < C; j++) // values in the cells of new // array are updated psa[i][j] = psa[i - 1][j] + psa[i][j - 1] - psa[i - 1][j - 1] + a[i][j]; } // displaying the values of the new array for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) cout << psa[i][j] << " "; cout << "\n"; }}// driver codeint 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
// Java program to find prefix sum of 2D arrayimport java.util.*;class GFG { // calculating new array 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]; // Filling first row and first column 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]; // updating the values in the // cells as per the general formula. for (int i = 1; i < R; i++) for (int j = 1; j < C; j++) // values in the cells of new array // are updated 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(); } } // driver code 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
# Python Program to find # prefix sum of 2d arrayR = 4C = 5# calculating new arraydef prefixSum2D(a) : global C, R psa = [[0 for x in range(C)] for y in range(R)] psa[0][0] = a[0][0] # Filling first row # and first column 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]) # updating the values in # the cells as per the # general formula for i in range(1, R) : for j in range(1, C) : # values in the cells of # new array are updated psa[i][j] = (psa[i - 1][j] + psa[i][j - 1] - psa[i - 1][j - 1] + a[i][j]) # displaying the values # of the new array for i in range(0, R) : for j in range(0, C) : print (psa[i][j], end = " ") print ()# Driver Codea = [[ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ]]prefixSum2D(a)# This code is contributed by # Manish Shaw(manishshaw1) |
C#
// C# program to find prefix// sum of 2D arrayusing System;class GFG { // calculating new array 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]; // Filling first row // and first column 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]; // updating the values in the // cells as per the general formula. for (int i = 1; i < R; i++) for (int j = 1; j < C; j++) // values in the cells of // new array are updated 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(); } } // Driver Code 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); }}// This code is contributed by manishshaw1 |
PHP
<?php// PHP Program to find // prefix sum of 2d array$R = 4;$C = 5;// calculating new arrayfunction prefixSum2D($a){ global $C, $R; $psa = array(); $psa[0][0] = $a[0][0]; // Filling first row // and first column 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]; // updating the values in // the cells as per the // general formula for ($i = 1; $i < $R; $i++) { for ($j = 1; $j < $C; $j++) // values in the cells of // new array are updated $psa[$i][$j] = $psa[$i - 1][$j] + $psa[$i][$j - 1] - $psa[$i - 1][$j - 1] + $a[$i][$j]; } // displaying the values // of the new array for ($i = 0; $i < $R; $i++) { for ($j = 0; $j < $C; $j++) echo ($psa[$i][$j]. " "); echo ("\n"); }}// Driver Code$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);// This code is contributed by // Manish Shaw(manishshaw1)?> |
Javascript
<script>// Javascript program to find prefix sum of 2D array// calculating new arrayfunction 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]; // Filling first row and first column 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]; // updating the values in the // cells as per the general formula. for (let i = 1; i < R; i++) for (let j = 1; j < C; j++) // values in the cells of new array // are updated 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>"); }}// driver codelet a=[[ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ]];prefixSum2D(a);// This code is contributed by avanitrachhadiya2155</script> |
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) { //vertical prefixsum for (int j = 0; j < n; j++) { for (int i = 1; i < n; i++) { arr[i][j] += arr[i-1][j]; } } //horizontal prefixsum 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) { // vertical prefixsum for (int j = 0; j < n; j++) { for (int i = 1; i < n; i++) { arr[i][j] += arr[i - 1][j]; } } // horizontal prefixsum 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(); } }}// This code is contributed by ishankhandelwals. |
Python3
def prefixsum(arr, n): # vertical prefixsum for j in range(n): for i in range(1, n): arr[i][j] += arr[i - 1][j] # horizontal prefixsum 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() # Driver Coden = 3arr = [[10,20,30],[5,10,20],[2,4,6]]prefixsum(arr,n)printarr(arr,n) # This code is contributed by# Vibhu Karnwal |
C#
// C# code for above approachusing 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]; } } //horizontal prefixsum 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); }}// This code is contributed by ishankhandelwals. |
Javascript
// Js code for above approachfunction prefixSum(arr, n) { //vertical prefixsum for (let j = 0; j < n; j++) { for (let i = 1; i < n; i++) { arr[i][j] += arr[i - 1][j]; } } //horizontal prefixsum 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);// This code is contributed by ishankhandelwals. |
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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

