Range sum queries without updates
Given an array arr of integers of size n. We need to compute the sum of elements from index i to index j. The queries consisting of i and j index values will be executed multiple times.
Examples:
Input : arr[] = {1, 2, 3, 4, 5}
i = 1, j = 3
i = 2, j = 4
Output : 9
12
Input : arr[] = {1, 2, 3, 4, 5}
i = 0, j = 4
i = 1, j = 2
Output : 15
5
A Simple Solution is to compute the sum for every query.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
int rangeSum( int arr[], int n, int i, int j) {
int sum = 0;
for ( int k = i; k <= j; k++) {
sum += arr[k];
}
return sum;
}
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << rangeSum(arr, n, 1, 3) << endl;
cout << rangeSum(arr, n, 2, 4) << endl;
return 0;
}
|
Java
public class Main {
static int rangeSum( int [] arr, int i, int j) {
int sum = 0 ;
for ( int k = i; k <= j; k++) {
sum += arr[k];
}
return sum;
}
public static void main(String[] args) {
int [] arr = { 1 , 2 , 3 , 4 , 5 };
int n = arr.length;
System.out.println(rangeSum(arr, 1 , 3 ));
System.out.println(rangeSum(arr, 2 , 4 ));
}
}
|
Python3
def rangeSum(arr, n, i, j) :
sum = 0 ;
for k in range (i, j + 1 ) :
sum + = arr[k];
return sum ;
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 , 4 , 5 ];
n = len (arr);
print (rangeSum(arr, n, 1 , 3 ));
print (rangeSum(arr, n, 2 , 4 ));
|
C#
using System;
public class RangeSumCalculator
{
public static int RangeSum( int [] arr, int i, int j)
{
int sum = 0;
for ( int k = i; k <= j; k++)
{
sum += arr[k];
}
return sum;
}
public static void Main( string [] args)
{
int [] arr = { 1, 2, 3, 4, 5 };
int n = arr.Length;
Console.WriteLine(RangeSum(arr, 1, 3));
Console.WriteLine(RangeSum(arr, 2, 4));
}
}
|
Javascript
function GFG(arr, i, j) {
let sum = 0;
for (let k = i; k <= j; k++) {
sum += arr[k];
}
return sum;
}
function main() {
const arr = [1, 2, 3, 4, 5];
const n = arr.length;
console.log(GFG(arr, 1, 3));
console.log(GFG(arr, 2, 4));
}
main();
|
Output
9
12
Time Complexity: For each query, the time complexity will be O(j-i+1). The overall time complexity is O((j-i+1) * q), where q is the number of queries.
Space Complexity: O(1), not using any extra space.
An Efficient Solution is to precompute prefix sum. Let pre[i] stores sum of elements from arr[0] to arr[i]. To answer a query (i, j), we return pre[j] – pre[i-1].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void preCompute( int arr[], int n, int pre[])
{
pre[0] = arr[0];
for ( int i = 1; i < n; i++)
pre[i] = arr[i] + pre[i - 1];
}
int rangeSum( int i, int j, int pre[])
{
if (i == 0)
return pre[j];
return pre[j] - pre[i - 1];
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
int pre[n];
preCompute(arr, n, pre);
cout << rangeSum(1, 3, pre) << endl;
cout << rangeSum(2, 4, pre) << endl;
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
class GFG {
public static void preCompute( int arr[], int n,
int pre[])
{
pre[ 0 ] = arr[ 0 ];
for ( int i = 1 ; i < n; i++)
pre[i] = arr[i] + pre[i - 1 ];
}
public static int rangeSum( int i, int j, int pre[])
{
if (i == 0 )
return pre[j];
return pre[j] - pre[i - 1 ];
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 , 5 };
int n = arr.length;
int pre[] = new int [n];
preCompute(arr, n, pre);
System.out.println(rangeSum( 1 , 3 , pre));
System.out.println(rangeSum( 2 , 4 , pre));
}
}
|
Python3
def preCompute(arr, n, prefix):
prefix[ 0 ] = arr[ 0 ]
for i in range ( 1 , n):
prefix[i] = prefix[i - 1 ] + arr[i]
def rangeSum(l, r):
if l = = 0 :
print (prefix[r])
return
print (prefix[r] - prefix[l - 1 ])
arr = [ 1 , 2 , 3 , 4 , 5 ]
n = len (arr)
prefix = [ 0 for i in range (n)]
preCompute(arr, n, prefix)
rangeSum( 1 , 3 )
rangeSum( 2 , 4 )
|
C#
using System;
class GFG {
public static void preCompute( int [] arr, int n,
int [] pre)
{
pre[0] = arr[0];
for ( int i = 1; i < n; i++)
pre[i] = arr[i] + pre[i - 1];
}
public static int rangeSum( int i, int j, int [] pre)
{
if (i == 0)
return pre[j];
return pre[j] - pre[i - 1];
}
public static void Main()
{
int [] arr = { 1, 2, 3, 4, 5 };
int n = arr.Length;
int [] pre = new int [n];
preCompute(arr, n, pre);
Console.WriteLine(rangeSum(1, 3, pre));
Console.WriteLine(rangeSum(2, 4, pre));
}
}
|
Javascript
<script>
let pre = new Array(1000,0);
function preCompute(arr, n)
{
pre[0] = arr[0];
for (let i = 1; i < n; i++)
pre[i] = arr[i] + pre[i - 1];
}
function rangeSum(i, j, pre)
{
if (i == 0)
return pre[j];
return pre[j] - pre[i - 1];
}
let arr = [1, 2, 3, 4, 5];
let n = arr.length;
preCompute(arr, n);
document.write(rangeSum(1, 3, pre)+ "<br>" );
document.write(rangeSum(2, 4, pre));
</script>
|
Here time complexity of every range sum query is O(1) and the overall time complexity is O(n).
Auxiliary Space required = O(n), where n is the size of the given array.
The question becomes complicated when updates are also allowed. In such situations when using advanced data structures like Segment Tree or Binary Indexed Tree.
This article is contributed by <Rahul Chawla.
Last Updated :
05 Dec, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...