Range maximum query using Sparse Table
Last Updated :
04 Jun, 2021
Given an array arr[], the task is to answer queries to find the maximum of all the elements in the index range arr[L…R].
Examples:
Input: arr[] = {6, 7, 4, 5, 1, 3}, q[][] = {{0, 5}, {3, 5}, {2, 4}}
Output:
7
5
5
Input: arr[] = {3, 34, 1}, q[][] = {{1, 2}}
Output:
34
Approach: A similar problem to answer range minimum queries has been discussed here. The same approach can be modified to answer range maximum queries. Below is the modification:
// Maximum of single element subarrays is same
// as the only element
lookup[i][0] = arr[i]
// If lookup[0][2] ? lookup[4][2],
// then lookup[0][3] = lookup[0][2]
If lookup[i][j-1] ? lookup[i+2j-1-1][j-1]
lookup[i][j] = lookup[i][j-1]
// If lookup[0][2] < lookup[4][2],
// then lookup[0][3] = lookup[4][2]
Else
lookup[i][j] = lookup[i+2j-1-1][j-1]
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define MAX 500
int lookup[MAX][MAX];
void buildSparseTable( int arr[], int n)
{
for ( int i = 0; i < n; i++)
lookup[i][0] = arr[i];
for ( int j = 1; (1 << j) <= n; j++) {
for ( int i = 0; (i + (1 << j) - 1) < n; i++) {
if (lookup[i][j - 1] > lookup[i + (1 << (j - 1))][j - 1])
lookup[i][j] = lookup[i][j - 1];
else
lookup[i][j] = lookup[i + (1 << (j - 1))][j - 1];
}
}
}
int query( int L, int R)
{
int j = ( int )log2(R - L + 1);
if (lookup[L][j] >= lookup[R - (1 << j) + 1][j])
return lookup[L][j];
else
return lookup[R - (1 << j) + 1][j];
}
int main()
{
int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 };
int n = sizeof (a) / sizeof (a[0]);
buildSparseTable(a, n);
cout << query(0, 4) << endl;
cout << query(4, 7) << endl;
cout << query(7, 8) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static final int MAX = 500 ;
static int lookup[][] = new int [MAX][MAX];
static void buildSparseTable( int arr[], int n)
{
for ( int i = 0 ; i < n; i++)
lookup[i][ 0 ] = arr[i];
for ( int j = 1 ; ( 1 << j) <= n; j++) {
for ( int i = 0 ; (i + ( 1 << j) - 1 ) < n; i++) {
if (lookup[i][j - 1 ] > lookup[i + ( 1 << (j - 1 ))][j - 1 ])
lookup[i][j] = lookup[i][j - 1 ];
else
lookup[i][j] = lookup[i + ( 1 << (j - 1 ))][j - 1 ];
}
}
}
static int query( int L, int R)
{
int j = ( int )Math.log(R - L + 1 );
if (lookup[L][j] >= lookup[R - ( 1 << j) + 1 ][j])
return lookup[L][j];
else
return lookup[R - ( 1 << j) + 1 ][j];
}
public static void main(String args[])
{
int a[] = { 7 , 2 , 3 , 0 , 5 , 10 , 3 , 12 , 18 };
int n = a.length;
buildSparseTable(a, n);
System.out.println(query( 0 , 4 ));
System.out.println(query( 4 , 7 ));
System.out.println(query( 7 , 8 ));
}
}
|
Python3
from math import log
MAX = 500
lookup = [[ 0 for i in range ( MAX )]
for i in range ( MAX )]
def buildSparseTable(arr, n):
for i in range (n):
lookup[i][ 0 ] = arr[i]
i, j = 0 , 1
while ( 1 << j) < = n:
while (i + ( 1 << j) - 1 ) < n:
if (lookup[i][j - 1 ] >
lookup[i + ( 1 << (j - 1 ))][j - 1 ]):
lookup[i][j] = lookup[i][j - 1 ]
else :
lookup[i][j] = lookup[i + ( 1 << (j - 1 ))][j - 1 ]
i + = 1
j + = 1
def query(L, R):
j = int (log(R - L + 1 ))
if (lookup[L][j] > = lookup[R - ( 1 << j) + 1 ][j]):
return lookup[L][j]
else :
return lookup[R - ( 1 << j) + 1 ][j]
a = [ 7 , 2 , 3 , 0 , 5 , 10 , 3 , 12 , 18 ]
n = len (a)
buildSparseTable(a, n);
print (query( 0 , 4 ))
print (query( 4 , 7 ))
print (query( 7 , 8 ))
|
C#
using System;
class GFG {
static int MAX = 500;
static int [, ] lookup = new int [MAX, MAX];
static void buildSparseTable( int [] arr, int n)
{
for ( int i = 0; i < n; i++)
lookup[i, 0] = arr[i];
for ( int j = 1; (1 << j) <= n; j++) {
for ( int i = 0; (i + (1 << j) - 1) < n; i++) {
if (lookup[i, j - 1] > lookup[i + (1 << (j - 1)), j - 1])
lookup[i, j] = lookup[i, j - 1];
else
lookup[i, j] = lookup[i + (1 << (j - 1)), j - 1];
}
}
}
static int query( int L, int R)
{
int j = ( int )Math.Log(R - L + 1);
if (lookup[L, j] >= lookup[R - (1 << j) + 1, j])
return lookup[L, j];
else
return lookup[R - (1 << j) + 1, j];
}
public static void Main(String[] args)
{
int [] a = { 7, 2, 3, 0, 5, 10, 3, 12, 18 };
int n = a.Length;
buildSparseTable(a, n);
Console.WriteLine(query(0, 4));
Console.WriteLine(query(4, 7));
Console.WriteLine(query(7, 8));
}
}
|
Javascript
<script>
let MAX = 500;
let lookup = new Array();
for (let i = 0; i < MAX; i++)
{
let temp = [];
for (let j = 0; j < MAX; j++)
{
temp.push([])
}
lookup.push(temp)
}
function buildSparseTable(arr, n)
{
for (let i = 0; i < n; i++)
lookup[i][0] = arr[i];
for (let j = 1; (1 << j) <= n; j++) {
for (let i = 0; (i + (1 << j) - 1) < n; i++) {
if (lookup[i][j - 1] > lookup[i + (1 << (j - 1))][j - 1])
lookup[i][j] = lookup[i][j - 1];
else
lookup[i][j] = lookup[i + (1 << (j - 1))][j - 1];
}
}
}
function query(L, R)
{
let j = Math.floor(Math.log2(R - L + 1));
if (lookup[L][j] >= lookup[R - (1 << j) + 1][j])
return lookup[L][j];
else
return lookup[R - (1 << j) + 1][j];
}
let a = [ 7, 2, 3, 0, 5, 10, 3, 12, 18 ];
let n = a.length;
buildSparseTable(a, n);
document.write(query(0, 4) + "<br>" );
document.write(query(4, 7) + "<br>" );
document.write(query(7, 8) + "<br>" );
</script>
|
So sparse table method supports query operation in O(1) time with O(n Log n) preprocessing time and O(n Log n) space.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...