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.
Share your thoughts in the comments
Please Login to comment...