PreComputation Technique on Arrays (original) (raw)

Last Updated : 23 Jul, 2025

**Precomputation refers to the process of pre-calculating and storing the results of certain computations or data structures(array in this case) in advance, in order to speed up the execution time of a program. This can be useful in situations where the same calculations are needed multiple times, as it avoids the need to recalculate them every time.

**This technique relies on fast retreival of already stored data rather than recalculation.

Some Common Pre-Computation Techniques used on Array:

Though pre-computation can be done in various ways over a wide range of questions, in this section we will look at some of the popular techniques of pre-computation:

Prefix/Suffix on 1-D Array:

A prefix array **PRE[] is defined on an array **ARR[], such that for each index '**i' PRE[i] stores the information about the values from ARR[0] to ARR[i]. This information can be in the form of prefix sum, prefix max, prefix gcd, etc.

Let's construct prefix array for ARR[] = {4, 2, 1, -1, 3}, to do this we can simply iterate ARR[] from **0 to **size-1, and store **PRE[i]=ARR[i]+PRE[i-1], after doing this we have PRE[] = {4, 6, 7, 6, 9}

**Why do we need this Prefix Array?

Below is the code to construct a Prefix Sum and Suffix Sum array:

C++ `

#include using namespace std;

// This function prints the array void print(int arr[], int N) { for (int i = 0; i < N; i++) { cout << arr[i] << " "; } cout << endl; }

// This function calculates the PrefixSum // of the array void PrefixSum(int ARR[], int N) {

// PRE[] array stores the result
int PRE[N];
for (int i = 0; i < N; i++) {

    // At index 0, no previous values
    // are present
    if (i == 0)
        PRE[i] = ARR[i];
    else
        PRE[i] = PRE[i - 1] + ARR[i];
}
cout << "Prefix Sum: ";
print(PRE, N);

}

// This function finds the Suffix // sum of the array void SuffixSum(int ARR[], int N) {

// This array stores the result
int SUF[N];
for (int i = N - 1; i >= 0; i--) {

    // At index N-1, there is no suffix
    // value available
    if (i == N - 1)
        SUF[i] = ARR[i];
    else
        SUF[i] = SUF[i + 1] + ARR[i];
}
cout << "Suffix Sum: ";
print(SUF, N);

}

// Driver code int main() { int N = 5; int ARR[N] = { 4, 2, 1, -1, 3 }; cout << "Given Array: "; print(ARR, N);

// Funtion call to calculate prefix sum
PrefixSum(ARR, N);

// Function call to calculate suffix sum
SuffixSum(ARR, N);
return 0;

}

Java

public class PrefixSuffixSum {

// This function prints the array
static void print(int[] arr, int N) {
    for (int i = 0; i < N; i++) {
        System.out.print(arr[i] + " ");
    }
    System.out.println();
}

// This function calculates the PrefixSum of the array
static void prefixSum(int[] arr, int N) {
    // PRE[] array stores the result
    int[] PRE = new int[N];
    for (int i = 0; i < N; i++) {
        // At index 0, no previous values are present
        if (i == 0)
            PRE[i] = arr[i];
        else
            PRE[i] = PRE[i - 1] + arr[i];
    }
    System.out.print("Prefix Sum: ");
    print(PRE, N);
}

// This function finds the Suffix sum of the array
static void suffixSum(int[] arr, int N) {
    // This array stores the result
    int[] SUF = new int[N];
    for (int i = N - 1; i >= 0; i--) {
        // At index N-1, there is no suffix value available
        if (i == N - 1)
            SUF[i] = arr[i];
        else
            SUF[i] = SUF[i + 1] + arr[i];
    }
    System.out.print("Suffix Sum: ");
    print(SUF, N);
}

// Driver code
public static void main(String[] args) {
    int N = 5;
    int[] ARR = { 4, 2, 1, -1, 3 };
    System.out.print("Given Array: ");
    print(ARR, N);

    // Function call to calculate prefix sum
    prefixSum(ARR, N);

    // Function call to calculate suffix sum
    suffixSum(ARR, N);
}

} //This code is contriuted by chinmaya121221

Python3

This function prints the array

def print_array(arr, N): for i in range(N): print(arr[i], end = " ") print()

This function calculates the PrefixSum

of the array

def PrefixSum(ARR, N):

# PRE[] array stores the result
PRE = [0] * N
for i in range(N):

    # At index 0, no previous values
    # are present
    if (i == 0):
        PRE[i] = ARR[i]
    else:
        PRE[i] = PRE[i - 1] + ARR[i]
print("Prefix Sum: ", end = "")
print_array(PRE, N)

This function finds the Suffix

sum of the array

def SuffixSum(ARR, N):

# This array stores the result
SUF = [0] * N
for i in range(N - 1, -1, -1):

    # At index N-1, there is no suffix
    # value available
    if (i == N - 1):
        SUF[i] = ARR[i]
    else:
        SUF[i] = SUF[i + 1] + ARR[i]
print("Suffix Sum: ", end = "")
print_array(SUF, N)

Driver code

if name == "main": N = 5 ARR = [4, 2, 1, -1, 3] print("Given Array: ", end = "") print_array(ARR, N)

# Funtion call to calculate prefix sum
PrefixSum(ARR, N)

# Function call to calculate suffix sum
SuffixSum(ARR, N)

C#

using System;

class Program { // This function prints the array static void Print(int[] arr, int N) { for (int i = 0; i < N; i++) { Console.Write(arr[i] + " "); } Console.WriteLine(); }

// This function calculates the PrefixSum of the array
static void PrefixSum(int[] ARR, int N)
{
    // PRE array stores the result
    int[] PRE = new int[N];
    for (int i = 0; i < N; i++)
    {
        // At index 0, no previous values are present
        if (i == 0)
            PRE[i] = ARR[i];
        else
            PRE[i] = PRE[i - 1] + ARR[i];
    }
    Console.Write("Prefix Sum: ");
    Print(PRE, N);
}

// This function finds the Suffix sum of the array
static void SuffixSum(int[] ARR, int N)
{
    // SUF array stores the result
    int[] SUF = new int[N];
    for (int i = N - 1; i >= 0; i--)
    {
        // At index N-1, there is no suffix value available
        if (i == N - 1)
            SUF[i] = ARR[i];
        else
            SUF[i] = SUF[i + 1] + ARR[i];
    }
    Console.Write("Suffix Sum: ");
    Print(SUF, N);
}

static void Main()
{
    int N = 5;
    int[] ARR = { 4, 2, 1, -1, 3 };
    Console.Write("Given Array: ");
    Print(ARR, N);

    // Function call to calculate prefix sum
    PrefixSum(ARR, N);

    // Function call to calculate suffix sum
    SuffixSum(ARR, N);
}

}

JavaScript

// This function prints the array function print(arr, N) { for (let i = 0; i < N; i++) { console.log(arr[i] + " "); } console.log(); }

// This function calculates the PrefixSum // of the array function PrefixSum(ARR, N) {

// PRE[] array stores the result
let PRE = [];
for (let i = 0; i < N; i++) {

    // At index 0, no previous values
    // are present
    if (i === 0)
        PRE[i] = ARR[i];
    else
        PRE[i] = PRE[i - 1] + ARR[i];
}
console.log("Prefix Sum: ");
print(PRE, N);

}

// This function finds the Suffix // sum of the array function SuffixSum(ARR, N) {

// This array stores the result
let SUF = [];
for (let i = N - 1; i >= 0; i--) {

    // At index N-1, there is no suffix
    // value available
    if (i === N - 1)
        SUF[i] = ARR[i];
    else
        SUF[i] = SUF[i + 1] + ARR[i];
}
console.log("Suffix Sum: ");
print(SUF, N);

}

// Driver code let N = 5; let ARR = [4, 2, 1, -1, 3]; console.log("Given Array: "); print(ARR, N);

PrefixSum(ARR, N);

SuffixSum(ARR, N);

`

Output

Given Array: 4 2 1 -1 3 Prefix Sum: 4 6 7 6 9 Suffix Sum: 9 5 3 2 3

Prefix on 2-D Array:

The above idea of Prefix on 1-D array can be expanded to 2-D array, where we have a 2-D array ARR[][] of size NxM and PRE[i][j] will store the information about the values from row 0 to 'i' and and column 0 to 'j' . Let's say we want to retrieve the sum of values of submatrice [i1, j1] to [i2, j2], we can simply use our 2-D prefix sum array to achieve this by simple Inclusion Exclusion principle PRE[i2][j2] - PRE[i2][j1-1] - PRE[i1-1][j2] + PRE[i1-1][j1-1].

Below is the code construct prefix sum for 2-D array:

C++ `

// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;

void print(vector<vector >& arr, int N, int M) { for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cout << arr[i][j] << " "; } cout << endl; } }

void PrefixSum(vector<vector >& ARR, int N, int M) { vector<vector > PRE(N, vector(M)); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { int x = 0; int y = 0; int z = 0; if (i - 1 >= 0) x = PRE[i - 1][j]; if (j - 1 >= 0) y = PRE[i][j - 1]; if (i - 1 >= 0 && j - 1 >= 0) z = PRE[i - 1][j - 1]; PRE[i][j] = ARR[i][j] + x + y - z; } } cout << "Give Array:" << endl; print(ARR, N, M); cout << "Prefix Sum Array:" << endl; print(PRE, N, M); }

// Drivers code int main() { int N = 4; int M = 4;

vector<vector<int> > ARR = { { 1, 1, 1, 1 },
                             { 1, 1, 1, 1 },
                             { 1, 1, 1, 1 },
                             { 1, 1, 1, 1 } };

// Function Call
PrefixSum(ARR, N, M);
return 0;

}

Java

import java.util.Arrays;

public class PrefixSum {

// Function to print a 2D array
static void print(int[][] arr, int N, int M)
{
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            System.out.print(arr[i][j] + " ");
        }
        System.out.println();
    }
}

// Function to compute the prefix sum of a 2D array
static void prefixSum(int[][] arr, int N, int M)
{
    int[][] pre = new int[N][M];

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            int x = 0, y = 0, z = 0;
            if (i - 1 >= 0)
                x = pre[i - 1][j];
            if (j - 1 >= 0)
                y = pre[i][j - 1];
            if (i - 1 >= 0 && j - 1 >= 0)
                z = pre[i - 1][j - 1];
            pre[i][j] = arr[i][j] + x + y - z;
        }
    }

    System.out.println("Given Array:");
    print(arr, N, M);
    System.out.println("Prefix Sum Array:");
    print(pre, N, M);
}

// Driver code
public static void main(String[] args)
{
    int N = 4;
    int M = 4;

    int[][] arr = { { 1, 1, 1, 1 },
                    { 1, 1, 1, 1 },
                    { 1, 1, 1, 1 },
                    { 1, 1, 1, 1 } };

    // Function call
    prefixSum(arr, N, M);
}

}

Python3

def print_matrix(matrix): # Function to print a 2D array for row in matrix: print(" ".join(map(str, row)))

def prefix_sum(matrix, n, m): # Function to compute the prefix sum of a 2D array prefix = [[0] * m for _ in range(n)]

for i in range(n):
    for j in range(m):
        x = 0 if i - 1 < 0 else prefix[i - 1][j]
        y = 0 if j - 1 < 0 else prefix[i][j - 1]
        z = 0 if i - 1 < 0 or j - 1 < 0 else prefix[i - 1][j - 1]

        prefix[i][j] = matrix[i][j] + x + y - z

print("Given Array:")
print_matrix(matrix)
print("Prefix Sum Array:")
print_matrix(prefix)

if name == "main": N = 4 M = 4

matrix = [
    [1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 1, 1]
]

# Function call
prefix_sum(matrix, N, M)

This code is contributed by shivamgupta0987654321

C#

using System;

class Program { // Function to print a 2D array static void Print(int[, ] arr, int N, int M) { for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { Console.Write(arr[i, j] + " "); } Console.WriteLine(); } }

// Function to compute the prefix sum of a 2D array
static void PrefixSum(int[, ] ARR, int N, int M)
{
    int[, ] PRE = new int[N, M];

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            int x = 0;
            int y = 0;
            int z = 0;

            // Calculate the sum of elements above the
            // current element
            if (i - 1 >= 0)
                x = PRE[i - 1, j];

            // Calculate the sum of elements to the left
            // of the current element
            if (j - 1 >= 0)
                y = PRE[i, j - 1];

            // Calculate the sum of elements in the
            // diagonal (top-left)
            if (i - 1 >= 0 && j - 1 >= 0)
                z = PRE[i - 1, j - 1];

            // Compute the prefix sum for the current
            // element
            PRE[i, j] = ARR[i, j] + x + y - z;
        }
    }

    // Print the given array
    Console.WriteLine("Given Array:");
    Print(ARR, N, M);

    // Print the computed prefix sum array
    Console.WriteLine("Prefix Sum Array:");
    Print(PRE, N, M);
}

// Driver code
static void Main()
{
    int N = 4;
    int M = 4;

    int[, ] ARR = { { 1, 1, 1, 1 },
                    { 1, 1, 1, 1 },
                    { 1, 1, 1, 1 },
                    { 1, 1, 1, 1 } };

    // Function Call
    PrefixSum(ARR, N, M);
}

}

JavaScript

function print(arr) { for (let i = 0; i < arr.length; i++) { console.log(arr[i].join(' ')); } console.log(); }

function calculatePrefixSum(ARR) { const N = ARR.length; const M = ARR[0].length;

// Initialize the prefix sum array
const PRE = new Array(N);
for (let i = 0; i < N; i++) {
    PRE[i] = new Array(M).fill(0);
}

for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
        let x = 0;
        let y = 0;
        let z = 0;

        if (i - 1 >= 0)
            x = PRE[i - 1][j];
        if (j - 1 >= 0)
            y = PRE[i][j - 1];
        if (i - 1 >= 0 && j - 1 >= 0)
            z = PRE[i - 1][j - 1];

        PRE[i][j] = ARR[i][j] + x + y - z;
    }
}

console.log("Given Array:");
print(ARR);
console.log("Prefix Sum Array:");
print(PRE);

}

// Driver's code const N = 4; const M = 4;

const ARR = [ [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1] ];

// Function Call calculatePrefixSum(ARR);

`

Output

Give Array: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Prefix Sum Array: 1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16

Hashing the Arrays data:

There are times when Hashing can be used for pre-computation and drastically reduce the time complexity of program. Suppose for various query we would require the first index of an element '**e' in the array. Instead of calculating this again and again, we can simply iterate on array once and hash the element to the first index it occurs to and finally retrieve this value in O(1) for each query.

Moreover Hashing can be combined with other precomputation techniques like prefix_sum in order to enhance the usability.

Practice Problems:

Problem Difficulty
Queries for the product of first N factorials Easy
Range sum queries without updates Easy
Range Queries for Frequencies of array elements Easy
Count Primes in Ranges Easy
Check in binary array the number represented by a subarray is odd or even Easy
GCDs of given index ranges in an array Easy
Mean of range in array Medium
Difference Array | Range update query in O(1) Medium
Range sum query using Sparse Table Medium
Number whose sum of XOR with given array range is maximum Medium
Number of primes in a subarray (with updates) Medium
Sum of Interval and Update with Number of Divisors Medium
Print modified array after multiple array range increment operations Medium
Sparse Table Hard
Range Minimum Query (Square Root Decomposition and Sparse Table) Hard
Range Query on array whose each element is XOR of index value and previous element Hard
Queries for GCD of all numbers of an array except elements in a given range Hard
Queries of nCr%p in O(1) time complexity Hard