Open In App
Related Articles

Prefix Sum of Matrix (Or 2D Array)

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

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.
 

prefix-sum-matrix


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 array
void 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 code
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

// Java program to find prefix sum of 2D array
import 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 array
R = 4
C = 5
 
# calculating new array
def 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 Code
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
# Manish Shaw(manishshaw1)

                    

C#

// C# program to find prefix
// sum of 2D array
using 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 array
function 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 array
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];
  
        // 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 code
let 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>

                    

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:

  1. Calculate the vertical prefix sum for each column.
  2. 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 Code
n = 3
arr = [[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 approach
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];
      }
    }
     
    //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 approach
function 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.

                    

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
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads