Open In App

Understanding Prefix Sums

Last Updated : 28 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In programming, prefix sum arrays are a simple and powerful technique. They make it easier to solve problems that involve finding the sum of numbers between two points in an array or working with subarrays.

Prefix Sum Defination

A prefix sum array is a derived array where each element at index i represents the sum of the original array’s elements from index 0 to i.

Why is it called "prefix" ?

Because it deals with the "prefix" or beginning portion of the array. For any index i, the prefix sum at i is the total of all elements before or up to that point.

Mathematical Definition:

Let the original array be: arr[] = [a0, a1, a2, ..., an-i].
The prefix sum array is: prefix[i] = a0 + a1 + a2 + ... + ai

So,

  • prefix[0] = arr[0]
  • prefix[1] = arr[0] + arr[1]
  • prefix[2] = arr[0] + arr[1] + arr[2]
  • ...

Example:

412034878

Prefix Sum Implementation

We can build the prefix sum array in linear time (O(n)) with a single pass through the array.

  • Initialize a prefix array of size n: Let prefix[0] = arr[0]
  • Traverse the original array once and do prefix[i] = arr[i] + prefix[i-1]
C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> buildPrefixSum(vector<int>& a) {
    int n = a.size();
    vector<int> prefix(n);
    
    // initialize the first element
    prefix[0] = a[0]; 

    for (int i = 1; i < n; ++i) {
        
        // add previous sum + current element
        prefix[i] = prefix[i - 1] + a[i];  
    }

    return prefix;
}

int main() {
    vector<int> a = {2, 4, 6, 8, 10};
    vector<int> prefix = buildPrefixSum(a);
    for (int val : prefix) {
        cout << val << " ";
    }
    cout << endl;
    return 0;
}
Java
import java.util.ArrayList;

class GfG {
    public static ArrayList<Integer> buildPrefixSum(int[] a) {
        int n = a.length;
        ArrayList<Integer> prefix = new ArrayList<>();
        
        // initialize the first element
        prefix.add(a[0]); 

        for (int i = 1; i < n; ++i) {
            
            // add previous sum + current element
            prefix.add(prefix.get(i - 1) + a[i]);
        }

        return prefix;
    }

    public static void main(String[] args) {
        int[] a = {2, 4, 6, 8, 10};

        ArrayList<Integer> prefix = buildPrefixSum(a);

        for (int val : prefix) {
            System.out.print(val + " ");
        }
        System.out.println();
    }
}
Python
def build_prefix_sum(a):
    n = len(a)
    prefix = [0] * n
    
    # initialize the first element
    prefix[0] = a[0]

    for i in range(1, n):
        
        # add previous sum + current element
        prefix[i] = prefix[i - 1] + a[i]

    return prefix

if __name__ == "__main__":
    a = [2, 4, 6, 8, 10]

    prefix = build_prefix_sum(a)

    for val in prefix:
        print(val, end=" ")
    print()
C#
using System;
using System.Collections.Generic;

class GfG {
    public static List<int> buildPrefixSum(int[] a) {
        int n = a.Length;
        List<int> prefix = new List<int>();
        
        // initialize the first element
        prefix.Add(a[0]);

        for (int i = 1; i < n; ++i) {
            
            // add previous sum + current element
            prefix.Add(prefix[i - 1] + a[i]);
        }

        return prefix;
    }

    public static void Main() {
        int[] a = {2, 4, 6, 8, 10};
        List<int> prefix = buildPrefixSum(a);
        foreach (int val in prefix) {
            Console.Write(val + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
function buildPrefixSum(a) {
    let n = a.length;
    let prefix = new Array(n);

    // Initialize the first element
    prefix[0] = a[0];

    for (let i = 1; i < n; ++i) {
        
        // add previous sum + current element
        prefix[i] = prefix[i - 1] + a[i];
    }

    return prefix;
}

// Driver Code
let a = [2, 4, 6, 8, 101];
let prefix = buildPrefixSum(a);
for (let val of prefix) {
    process.stdout.write(val + " ");
}
console.log();

Output
2 6 12 20 30 

Time Complexity: O(n), The algorithm traverses the input array once and performs constant-time additions.
Auxiliary Space: O(n), a separate array of size n is created to store prefix sums.

In-Place Prefix Sum

Instead of building a separate prefix array, we directly modify the input array: arr[i] = arr[i - 1] + arr[i];

This is space-efficient:

  • Time Complexity: O(n)
  • Space Complexity: O(1) extra space
C++
#include <iostream>
#include <vector>
using namespace std;

// function to build prefix sum in-place
vector<int> buildPrefixSum(vector<int>& arr) {
    int n = arr.size();

    for (int i = 1; i < n; ++i) {
        // add previous sum + current element
        arr[i] = arr[i - 1] + arr[i];
    }
    
    return arr;
}

int main() {
    vector<int> arr = {2, 4, 6, 8, 10};

    vector<int> res = buildPrefixSum(arr);

    for (int val : res) {
        cout << val << " ";
    }
    cout << endl;

    return 0;
}
Java
import java.util.ArrayList;

class GfG {
    
    // function to build prefix sum in-place
    public static ArrayList<Integer> buildPrefixSum(int[] arr) {
        int n = arr.length;

        for (int i = 1; i < n; ++i) {
            
            // add previous sum + current element
            arr[i] = arr[i - 1] + arr[i];
        }

        ArrayList<Integer> res = new ArrayList<>();
        for (int val : arr) res.add(val);
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {2, 4, 6, 8, 10};

        ArrayList<Integer> res = buildPrefixSum(arr);

        for (int val : res) {
            System.out.print(val + " ");
        }
        System.out.println();
    }
}
Python
# function to build prefix sum in-place
def build_prefix_sum(arr):
    n = len(arr)

    for i in range(1, n):
        
        # add previous sum + current element
        arr[i] = arr[i - 1] + arr[i]

    return arr

if __name__ == "__main__":
    arr = [2, 4, 6, 8, 10]

    res = build_prefix_sum(arr)

    for val in res:
        print(val, end=" ")
    print()
C#
using System;
using System.Collections.Generic;

class GfG {
    
    // function to build prefix sum in-place
    public static List<int> buildPrefixSum(int[] arr) {
        int n = arr.Length;

        for (int i = 1; i < n; ++i) {
            
            // add previous sum + current element
            arr[i] = arr[i - 1] + arr[i];
        }

        List<int> res = new List<int>(arr);
        return res;
    }

    public static void Main() {
        int[] arr = {2, 4, 6, 8, 10};

        List<int> res = buildPrefixSum(arr);

        foreach (int val in res) {
            Console.Write(val + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
// function to build prefix sum in-place
function buildPrefixSum(arr) {
    let n = arr.length;

    for (let i = 1; i < n; ++i) {
        
        // add previous sum + current element
        arr[i] = arr[i - 1] + arr[i];
    }

    return arr;
}

// Driver Code
let arr = [2, 4, 6, 8, 10];

let res = buildPrefixSum(arr);

for (let val of res) {
    process.stdout.write(val + " ");
}
console.log();

Output
2 6 12 20 30 

Applications of Prefix Sum

  • Range sum queries
  • Subarray problems: count subarrays with certain properties (e.g., sum, XOR)
  • 2D prefix sums: used in image processing, matrix sum problems
  • Sliding window optimizations
  • Histogram-style range counting

Classic Problems That Use Prefix Sums

  • Range Sum Query
  • Subarray Sum Equals k
  • Number of Subarrays with Sum ≤ k
  • 2D Range Sum Queries
  • Longest Subarray with Given Sum

Practical example to better understanding

Given an array arr[] of integers and a list of queries queries[][], where each query is in the form [L, R], compute the sum of elements from index L to R (both inclusive) for each query.

Examples:

Input: arr[] = [2, 4, 6, 8, 10], queries[][] = [[1, 3], [0, 2]]
Output: [18, 12]
Explanation:
Query [1, 3] → 4 + 6 + 8 = 18
Query [0, 2] → 2 + 4 + 6 = 12

Input: arr[] = [5, 1, 3, 2], queries[][] = [[0, 1], [2, 3]]
Output: [6, 5]
Explanation:
Query [0, 1] → 5 + 1 = 6
Query [2, 3] → 3 + 2 = 5

[Approach] Using Prefix Sum - O(n + q) Time and O(n) Space

The idea is to precompute a prefix sum array where each element at index i stores the sum of elements from index 0 to i.
This allows each query [L, R] to be answered in constant time using: sum = prefix[R] - prefix[L - 1] (or prefix[R] if L == 0).

Mathematics Behind the Prefix Sum Approach:

Let the original array be: arr[] = [a0, a1, a2, ..., an-1]

We define a prefix sum array prefix[] such that: prefix[i] = a0 + a1 + a2 + ... + ai

Now, to compute the sum of elements from index L to R, we use:

  • If L > 0: sum(L, R) = prefix[R] - prefix[L - 1]
  • If L == 0: sum(0, R) = prefix[R]

This works because:

  • prefix[R] = a0 + a1 + ... + aL-1 + aL + ... + aR
  • prefix[L - 1] = a0 + a1 + ... + aL-1
  • So, prefix[R] - prefix[L - 1] = aL + aL+1 + ... + aR
C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> rangeSumQueries(vector<int>& arr, 
                            vector<vector<int>>& queries) {
    int n = arr.size();
    vector<int> prefix(n);
    vector<int> result;

    // build prefix sum array
    prefix[0] = arr[0];
    for (int i = 1; i < n; i++) {
        prefix[i] = prefix[i - 1] + arr[i];
    }

    // process each query
    for (auto& q : queries) {
        int L = q[0], R = q[1];
        int sum = prefix[R] - (L > 0 ? prefix[L - 1] : 0);
        result.push_back(sum);
    }

    return result;
}

int main() {
    vector<int> arr = {2, 4, 6, 8, 10};
    vector<vector<int>> queries = {{1, 3}, {0, 2}};

    vector<int> ans = rangeSumQueries(arr, queries);

    for (int val : ans) {
        cout << val << " ";
    }

    return 0;
}
Java
import java.util.ArrayList;

class GfG {
    public static ArrayList<Integer> rangeSumQueries(int[] arr, 
                                                int[][] queries) {
        int n = arr.length;
        int[] prefix = new int[n];
        ArrayList<Integer> result = new ArrayList<>();

        // build prefix sum array
        prefix[0] = arr[0];
        for (int i = 1; i < n; i++) {
            prefix[i] = prefix[i - 1] + arr[i];
        }

        // process each query
        for (int[] q : queries) {
            int L = q[0], R = q[1];
            int sum = prefix[R] - (L > 0 ? prefix[L - 1] : 0);
            result.add(sum);
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {2, 4, 6, 8, 10};
        int[][] queries = {{1, 3}, {0, 2}};

        ArrayList<Integer> ans = rangeSumQueries(arr, queries);

        for (int val : ans) {
            System.out.print(val + " ");
        }
    }
}
Python
def rangeSumQueries(arr, queries):
    n = len(arr)
    prefix = [0] * n
    result = []

    # build prefix sum array
    prefix[0] = arr[0]
    for i in range(1, n):
        prefix[i] = prefix[i - 1] + arr[i]

    # process each query
    for q in queries:
        L, R = q[0], q[1]
        sum = prefix[R] - (prefix[L - 1] if L > 0 else 0)
        result.append(sum)

    return result

if __name__ == "__main__":
    arr = [2, 4, 6, 8, 10]
    queries = [[1, 3], [0, 2]]

    ans = rangeSumQueries(arr, queries)

    for val in ans:
        print(val, end=' ')
C#
using System;
using System.Collections.Generic;

class GfG {
    public static List<int> rangeSumQueries(int[] arr,
                                        int[][] queries) {
        int n = arr.Length;
        int[] prefix = new int[n];
        List<int> result = new List<int>();

        // build prefix sum array
        prefix[0] = arr[0];
        for (int i = 1; i < n; i++) {
            prefix[i] = prefix[i - 1] + arr[i];
        }

        // process each query
        foreach (var q in queries) {
            int L = q[0], R = q[1];
            int sum = prefix[R] - (L > 0 ? prefix[L - 1] : 0);
            result.Add(sum);
        }

        return result;
    }

    public static void Main() {
        int[] arr = {2, 4, 6, 8, 10};
        int[][] queries = new int[][] {
            new int[] {1, 3},
            new int[] {0, 2}
        };

        List<int> ans = rangeSumQueries(arr, queries);

        foreach (int val in ans) {
            Console.Write(val + " ");
        }
    }
}
JavaScript
function rangeSumQueries(arr, queries) {
    const n = arr.length;
    const prefix = Array(n).fill(0);
    const result = [];

    // build prefix sum array
    prefix[0] = arr[0];
    for (let i = 1; i < n; i++) {
        prefix[i] = prefix[i - 1] + arr[i];
    }

    // process each query
    for (const q of queries) {
        let L = q[0], R = q[1];
        let sum = prefix[R] - (L > 0 ? prefix[L - 1] : 0);
        result.push(sum);
    }

    return result;
}

// Driver Code
const arr = [2, 4, 6, 8, 10];
const queries = [[1, 3], [0, 2]];

const ans = rangeSumQueries(arr, queries);

for (const val of ans) {
    process.stdout.write(val + " ");
}

Output
18 12 

Article Tags :

Explore