Pour compléter la réponse de ngoaho91.
La meilleure façon de résoudre ce problème est d'utiliser la structure de données de l'arborescence des segments. Cela vous permet de répondre à de telles requêtes dans O (log (n)), ce qui signifierait que la complexité totale de votre algorithme serait O (Q logn) où Q est le nombre de requêtes. Si vous utilisiez l'algorithme naïf, la complexité totale serait O (Q n) qui est évidemment plus lente.
Il y a cependant un inconvénient à l'utilisation des arbres de segments. Cela prend beaucoup de mémoire, mais souvent vous vous souciez moins de la mémoire que de la vitesse.
Je décrirai brièvement les algorithmes utilisés par ce DS:
L'arbre de segment n'est qu'un cas particulier d'un arbre de recherche binaire, où chaque nœud contient la valeur de la plage à laquelle il est affecté. Le nœud racine se voit attribuer la plage [0, n]. L'enfant gauche se voit attribuer la plage [0, (0 + n) / 2] et l'enfant droit [(0 + n) / 2 + 1, n]. De cette façon, l'arbre sera construit.
Créer un arbre :
/*
A[] -> array of original values
tree[] -> Segment Tree Data Structure.
node -> the node we are actually in: remember left child is 2*node, right child is 2*node+1
a, b -> The limits of the actual array. This is used because we are dealing
with a recursive function.
*/
int tree[SIZE];
void build_tree(vector<int> A, int node, int a, int b) {
if (a == b) { // We get to a simple element
tree[node] = A[a]; // This node stores the only value
}
else {
int leftChild, rightChild, middle;
leftChild = 2*node;
rightChild = 2*node+1; // Or leftChild+1
middle = (a+b) / 2;
build_tree(A, leftChild, a, middle); // Recursively build the tree in the left child
build_tree(A, rightChild, middle+1, b); // Recursively build the tree in the right child
tree[node] = max(tree[leftChild], tree[rightChild]); // The Value of the actual node,
//is the max of both of the children.
}
}
Arbre de requête
int query(int node, int a, int b, int p, int q) {
if (b < p || a > q) // The actual range is outside this range
return -INF; // Return a negative big number. Can you figure out why?
else if (p >= a && b >= q) // Query inside the range
return tree[node];
int l, r, m;
l = 2*node;
r = l+1;
m = (a+b) / 2;
return max(query(l, a, m, p, q), query(r, m+1, b, p, q)); // Return the max of querying both children.
}
Si vous avez besoin de plus d'explications, faites le moi savoir.
BTW, Segment Tree prend également en charge la mise à jour d'un seul élément ou d'une plage d'éléments dans O (log n)