Dada una array arr[] , la tarea es responder consultas para encontrar el máximo de todos los elementos en el rango de índice arr[L…R] .
Ejemplos:
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
Enfoque: aquí se ha discutido un problema similar para responder consultas de rango mínimo . El mismo enfoque se puede modificar para responder consultas de rango máximo. A continuación se muestra la modificación:
// 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]
A continuación se muestra la implementación del enfoque anterior:
C++
// C++ implementation of the approach #include <bits/stdc++.h> 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
<script> // Javascript implementation of the approach let 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. 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) } // Fills lookup array lookup[][] in bottom up manner function buildSparseTable(arr, n) { // Initialize M for the letervals with length 1 for (let i = 0; i < n; i++) lookup[i][0] = arr[i]; // Compute values from smaller to bigger letervals for (let j = 1; (1 << j) <= n; j++) { // Compute maximum value for all letervals with // size 2^j for (let 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] function 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 let j = Math.floor(Math.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 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>"); // This code is contributed by _saurabh_jaiswal. </script>
Producción:
7 12 18
Por lo tanto, el método de tabla dispersa admite la operación de consulta en tiempo O (1) con tiempo de preprocesamiento O (n Log n) y espacio O (n Log n).
Publicación traducida automáticamente
Artículo escrito por chaudhary_19 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA