web-dev-qa-db-fra.com

Structure de données pour vérifier si un tableau statique ne contient pas d'élément d'une plage donnée

Je suis bloqué pendant des heures sur la question de devoirs suivante pour la classe de structures de données:

On vous donne un ensemble statique S (c'est-à-dire que S ne change jamais) de n entiers de {1,. . . , u}.

Décrire une structure de données de taille O (n log u) qui peut répondre aux requêtes suivantes en O(1) time:

Empty(i, j) - renvoie VRAI si et seulement s'il n'y a pas d'élément dans S entre i et j (où i et j sont des entiers dans {1,..., u}).

Au début, j'ai pensé à utiliser un y-fast-trie.

En utilisant y-fast-trie, nous pouvons obtenir O(n) espace et O(loglogu) requête (en trouvant le successeur de i et en vérifiant s'il est plus grand) que j).

Mais O(loglogu) n'est pas O (1) ...

Ensuite, j'ai pensé que nous pourrions peut-être trier le tableau et créer un deuxième tableau de taille n + 1 des plages qui ne sont pas dans le tableau, puis dans la requête, nous vérifierions si [i, j] est une sous-plage de l'un des les plages mais je n'ai pas pensé à un moyen de le faire qui utilise O(nlogu) espace et peut répondre à la requête dans O (1).

Je n'ai aucune idée de comment résoudre ce problème et j'ai l'impression que je ne suis même pas proche de la solution, toute aide serait gentille.

19
Tomer Wolberg

Considérons une structure de données composée de

  • un tableau A[1,...,u] de taille u tel que A[i]=1 si i est présent dans S, et A[i]=0 sinon. Ce tableau peut être construit à partir de l'ensemble S dans O (n).

  • un tableau B[1,...,u] de taille u qui stocke la somme cumulée de A c'est-à-dire B[i] = A[1]+...+A[i]. Ce tableau peut être construit en O(u) à partir de A en utilisant la relation B[i] = B[i-1] + A[i] Pour tous i>1.

  • une fonction empty(i,j) qui renvoie la requête booléenne souhaitée. Si i==1, Définissez count = B[j], Sinon prenez count = B[j]-B[i-1]. Notez que count donne le nombre d'éléments distincts dans S compris entre [i,j]. Une fois que nous avons count, il suffit de retourner count==0. Clairement, chaque requête prend O (1).

Edit: Comme indiqué dans les commentaires, la taille de cette structure de données est O (u), ce qui ne correspond pas aux contraintes. Mais j'espère que cela donnera aux autres une cible approximative pour tirer.

0
mrpandey

Ce n'est pas une solution, mais impossible de l'écrire dans un commentaire. Il y a une idée de la façon de résoudre la tâche plus spécifique qui peut éventuellement aider à résoudre la tâche générique de la question.

La tâche spécifique est la même sauf le point suivant, u = 1024. De plus, ce n'est pas une solution finale, c'est un croquis (pour la tâche spécifique).

Création de structure de données:

  1. Créez un masque binaire pour U = {1, ..., u} - M = 0000 ..... 100001, où Mᵥ = 1 lorsque Uᵥ ∊ S, otherwice = 0.
  2. Enregistrez le masque de bits M en tant que tableau "entiers non signés 32" = G (32 éléments). Chaque élément de G contient 32 éléments de M.
  3. Combinez l'entier H = masque de bits où Hᵣ = 0 lorsque Gᵣ = 0, otherwice = 1
  4. Convertissez G en [~ # ~] g [~ # ~] qui est HashMap r en Gᵣ. [~ # ~] g [~ # ~] est G mais contient des enregistrements pour Gᵣ! = 0 uniquement.

Les images du pseudocode suivant utilisent 8 bits sauf 32, juste pour plus de simplicité.

Empty(i, j) {
   I = i / 32
   J = j / 32

   if I != J {

       if P == 0: return true

enter image description here

       if P(I) == 0: return true

enter image description here


       if P(J) == 0: return true

   } else {

9999

       if P(J=I) == 0: return true
   }

   return false
}
0