In this article we will learn about Range sum query using Sparse Table in JavaScript Array, The Sparse Table is a data structure that efficiently solves static range query problems. In the context of the range sum queries, Sparse Table precomputes and stores the sum of the ranges of elements in an array. This allows for fast retrieval of the sum of any range within the array.
These are the following approaches by using these we can Range sum query using a Sparse Table in JavaScript Array:
Table of Content
Precompute and Query (Naive)
- In the naive approach of implementing a Sparse Table for the range sum queries.
- We follow a straightforward process of precomputing the table and querying the sum for the given range.
Example: In this example, we are implementing the above-explained approach.
class GFG { constructor(arr) {
this .arr = arr;
this .n = arr.length;
this .table = Array.from({ length: this .n },
() => Array(Math.ceil(Math.log2( this .n)) + 1).fill(0));
this .buildSparseTable(arr);
}
buildSparseTable(arr) {
// Initialize table with the array elements
for (let i = 0; i < this .n; i++) {
this .table[i][0] = arr[i];
}
// Build sparse table using the dynamic programming
for (let j = 1; (1 << j) <= this .n; j++) {
for (let i = 0; i + (1 << j) - 1 < this .n; i++) {
this .table[i][j] = this .table[i][j - 1]
+ this .table[i + (1 << (j - 1))][j - 1];
}
}
}
queryNaive(left, right) {
let result = 0;
// Naively sum elements in the range
for (let i = left; i <= right; i++) {
result += this .arr[i];
}
return result;
}
} // Example Usage const arr = [1, 2, 3, 4, 5, 6, 7, 8]; const sparseTable = new GFG(arr);
// Query using Naive approach const sumNaive = sparseTable.queryNaive(2, 5); console.log( "Sum using Naive approach:" , sumNaive);
|
Sum using Naive approach: 18
Precompute and Query with Optimized Loop
- In this approach, we optimize the loop within query method to achieve the faster range sum queries.
- The optimization involves iterating through the sparse table in a more efficient way.
- Reducing the time complexity of range sum queries.
Example: In this example, we are implementing the above-explained approach.
class GFG { constructor(arr) {
this .table = this .buildSparseTable(arr);
}
// Build Sparse Table
buildSparseTable(arr) {
const n = arr.length;
const table = new Array(n).fill()
.map(() => new Array(Math.ceil(Math.log2(n)) + 1).fill(0));
// Fill the first column with the array values
for (let i = 0; i < n; i++) {
table[i][0] = arr[i];
}
// Build the sparse table using the dynamic programming
for (let j = 1; (1 << j) <= n; j++) {
for (let i = 0; i + (1 << j) <= n; i++) {
// Compute the minimum value in current range
table[i][j] = table[i][j - 1] + table[i + (1 << (j - 1))][j - 1];
}
}
return table;
}
// Optimized Query method
queryOptimized(left, right) {
let result = 0;
// Iterate through powers of 2 in descending order
for (let j = Math.floor(Math.log2(right - left + 1));
j >= 0; j--) {
// Check if the current power of 2 is within the range
if ((1 << j) <= right - left + 1) {
// Update the result and move to
// next non-overlapping range
result += this .table[left][j];
left += 1 << j;
}
}
return result;
}
} // Example Usage const arr = [1, 2, 3, 4, 5, 6, 7, 8]; const sparseTable = new GFG(arr);
// Query using Optimized approach const sumOptimized = sparseTable.queryOptimized(0, 0); console.log( "Sum using Optimized approach:" , sumOptimized);
|
Sum using Optimized approach: 1