# Range maximum query using Sparse Table

• Difficulty Level : Medium
• 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++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;``#define MAX 500` `// lookup[i][j] is going to store maximum``// value in arr[i..j]. Ideally lookup table``// size should not be fixed and should be``// determined using n Log n. It is kept``// constant to keep code simple.``int` `lookup[MAX][MAX];` `// Fills lookup array lookup[][] in bottom up manner``void` `buildSparseTable(``int` `arr[], ``int` `n)``{``    ``// Initialize M for the intervals with length 1``    ``for` `(``int` `i = 0; i < n; i++)``        ``lookup[i][0] = arr[i];` `    ``// Compute values from smaller to bigger intervals``    ``for` `(``int` `j = 1; (1 << j) <= n; j++) {` `        ``// Compute maximum value for all intervals with``        ``// size 2^j``        ``for` `(``int` `i = 0; (i + (1 << j) - 1) < n; i++) {` `            ``// For arr[2][10], we compare arr[lookup[0][7]]``            ``// and arr[lookup[3][10]]``            ``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];``        ``}``    ``}``}` `// Returns maximum of arr[L..R]``int` `query(``int` `L, ``int` `R)``{``    ``// Find highest power of 2 that is smaller``    ``// than or equal to count of elements in given``    ``// range``    ``// For [2, 10], j = 3``    ``int` `j = (``int``)log2(R - L + 1);` `    ``// Compute maximum of last 2^j elements with first``    ``// 2^j elements in range``    ``// For [2, 10], we compare arr[lookup[0][3]] and``    ``// arr[lookup[3][3]]``    ``if` `(lookup[L][j] >= lookup[R - (1 << j) + 1][j])``        ``return` `lookup[L][j];` `    ``else``        ``return` `lookup[R - (1 << j) + 1][j];``}` `// Driver program``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

 `// Java implementation of the approach``import` `java.util.*;``class` `GFG {` `    ``static` `final` `int` `MAX = ``500``;` `    ``// lookup[i][j] is going to store maximum``    ``// value in arr[i..j]. Ideally lookup table``    ``// size should not be fixed and should be``    ``// determined using n Log n. It is kept``    ``// constant to keep code simple.``    ``static` `int` `lookup[][] = ``new` `int``[MAX][MAX];` `    ``// Fills lookup array lookup[][] in bottom up manner``    ``static` `void` `buildSparseTable(``int` `arr[], ``int` `n)``    ``{``        ``// Initialize M for the intervals with length 1``        ``for` `(``int` `i = ``0``; i < n; i++)``            ``lookup[i][``0``] = arr[i];` `        ``// Compute values from smaller to bigger intervals``        ``for` `(``int` `j = ``1``; (``1` `<< j) <= n; j++) {` `            ``// Compute maximum value for all intervals with``            ``// size 2^j``            ``for` `(``int` `i = ``0``; (i + (``1` `<< j) - ``1``) < n; i++) {` `                ``// For arr[2][10], we compare arr[lookup[0][7]]``                ``// and arr[lookup[3][10]]``                ``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``];``            ``}``        ``}``    ``}` `    ``// Returns maximum of arr[L..R]``    ``static` `int` `query(``int` `L, ``int` `R)``    ``{``        ``// Find highest power of 2 that is smaller``        ``// than or equal to count of elements in given``        ``// range``        ``// For [2, 10], j = 3``        ``int` `j = (``int``)Math.log(R - L + ``1``);` `        ``// Compute maximum of last 2^j elements with first``        ``// 2^j elements in range``        ``// For [2, 10], we compare arr[lookup[0][3]] and``        ``// arr[lookup[3][3]]``        ``if` `(lookup[L][j] >= lookup[R - (``1` `<< j) + ``1``][j])``            ``return` `lookup[L][j];` `        ``else``            ``return` `lookup[R - (``1` `<< j) + ``1``][j];``    ``}` `    ``// Driver program``    ``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

 `# Python3 implementation of the approach``from` `math ``import` `log``MAX` `=` `500` `# lookup[i][j] is going to store maximum``# value in arr[i..j]. Ideally lookup table``# size should not be fixed and should be``# determined using n Log n. It is kept``# constant to keep code simple.``lookup ``=` `[[``0` `for` `i ``in` `range``(``MAX``)]``             ``for` `i ``in` `range``(``MAX``)]` `# Fills lookup array lookup[][]``# in bottom up manner``def` `buildSparseTable(arr, n):` `    ``# Initialize M for the intervals``    ``# with length 1``    ``for` `i ``in` `range``(n):``        ``lookup[i][``0``] ``=` `arr[i]` `    ``# Compute values from smaller``    ``# to bigger intervals``    ``i, j ``=` `0``, ``1``    ``while` `(``1` `<< j) <``=` `n:` `        ``# Compute maximum value for``        ``# all intervals with size 2^j``        ``while` `(i ``+` `(``1` `<< j) ``-` `1``) < n:` `            ``# For arr[2][10], we compare arr[lookup[0][7]]``            ``# and arr[lookup[3][10]]``            ``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` `# Returns maximum of arr[L..R]``def` `query(L, R):``    ` `    ``# Find highest power of 2 that is smaller``    ``# than or equal to count of elements in given``    ``# range``    ``# For [2, 10], j = 3``    ``j ``=` `int``(log(R ``-` `L ``+` `1``))` `    ``# Compute maximum of last 2^j elements with first``    ``# 2^j elements in range``    ``# For [2, 10], we compare arr[lookup[0][3]] and``    ``# arr[lookup[3][3]]``    ``if` `(lookup[L][j] >``=` `lookup[R ``-` `(``1` `<< j) ``+` `1``][j]):``        ``return` `lookup[L][j]` `    ``else``:``        ``return` `lookup[R ``-` `(``1` `<< j) ``+` `1``][j]` `# Driver Code``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``))` `# This code is contributed by Mohit Kumar`

## C#

 `// Java implementation of the approach``using` `System;``class` `GFG {` `    ``static` `int` `MAX = 500;` `    ``// lookup[i][j] is going to store maximum``    ``// value in arr[i..j]. Ideally lookup table``    ``// size should not be fixed and should be``    ``// determined using n Log n. It is kept``    ``// constant to keep code simple.``    ``static` `int``[, ] lookup = ``new` `int``[MAX, MAX];` `    ``// Fills lookup array lookup[][] in bottom up manner``    ``static` `void` `buildSparseTable(``int``[] arr, ``int` `n)``    ``{``        ``// Initialize M for the intervals with length 1``        ``for` `(``int` `i = 0; i < n; i++)``            ``lookup[i, 0] = arr[i];` `        ``// Compute values from smaller to bigger intervals``        ``for` `(``int` `j = 1; (1 << j) <= n; j++) {` `            ``// Compute maximum value for all intervals with``            ``// size 2^j``            ``for` `(``int` `i = 0; (i + (1 << j) - 1) < n; i++) {` `                ``// For arr[2][10], we compare arr[lookup[0][7]]``                ``// and arr[lookup[3][10]]``                ``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];``            ``}``        ``}``    ``}` `    ``// Returns maximum of arr[L..R]``    ``static` `int` `query(``int` `L, ``int` `R)``    ``{``        ``// Find highest power of 2 that is smaller``        ``// than or equal to count of elements in given``        ``// range``        ``// For [2, 10], j = 3``        ``int` `j = (``int``)Math.Log(R - L + 1);` `        ``// Compute maximum of last 2^j elements with first``        ``// 2^j elements in range``        ``// For [2, 10], we compare arr[lookup[0][3]] and``        ``// arr[lookup[3][3]]``        ``if` `(lookup[L, j] >= lookup[R - (1 << j) + 1, j])``            ``return` `lookup[L, j];` `        ``else``            ``return` `lookup[R - (1 << j) + 1, j];``    ``}` `    ``// Driver program``    ``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

 ``

Output:

```7
12
18```

So sparse table method supports query operation in O(1) time with O(n Log n) preprocessing time and O(n Log n) space.

My Personal Notes arrow_drop_up