Supposons que l'on nous donne deux nombres et et que nous voulons trouver pour l \ le i, \, j \ le r .
L'algorithme naïf vérifie simplement toutes les paires possibles; par exemple en rubis, nous aurions:
def max_xor(l, r)
max = 0
(l..r).each do |i|
(i..r).each do |j|
if (i ^ j > max)
max = i ^ j
end
end
end
max
end
Je sens que nous pouvons faire mieux que quadratique. Existe-t-il un meilleur algorithme pour ce problème?
algorithms
algorithms
machine-learning
statistics
testing
terminology
asymptotics
landau-notation
reference-request
optimization
scheduling
complexity-theory
time-complexity
lower-bounds
communication-complexity
computational-geometry
computer-architecture
cpu-cache
cpu-pipelines
operating-systems
multi-tasking
algorithms
algorithm-analysis
education
correctness-proof
didactics
algorithms
data-structures
time-complexity
computational-geometry
algorithms
combinatorics
efficiency
partitions
complexity-theory
satisfiability
artificial-intelligence
operating-systems
performance
terminology
computer-architecture
Jacopo Notarstefano
la source
la source
j
couriri+1..r
eti
courirl...r-1
pour être précis.Réponses:
Nous pouvons atteindre un temps d'exécution linéaire dans la longueur de la représentation binaire de et :n l r
Le préfixe dans la représentation binaire de et , qui est le même pour les deux valeurs, est également le même pour toutes les valeurs entre elles. Ces bits seront donc toujours .p l r 0
Puisque , le bit suivant ce préfixe sera dans et dans . De plus, les nombres et sont tous deux dans l'intervalle.r>l 1 r 0 l p10n−|p|−1 p01n−|p|−1
Le maximum que nous recherchons est donc .0| p |1n - | p |
la source
Il est possible de le faire en temps .O (logr )
Le XOR maximum possible de deux entiers quelconques à partir d'un intervalle peut être déterminé à partir de l ⊕ r , en supposant que l , r soit des entiers. Cette valeur est égale à 2 p - 1 , où p est la plus petite valeur telle que 2 p soit supérieur à l ⊕ r .[ l , r ] l ⊕ r l , r 2p- 1 p 2p l ⊕ r
Voici une implémentation en C ++
la source
Nous devons maximiser le xor entre «petit» et «haut». Prenons donc un exemple pour comprendre cela.
5 xor 2 = 101 xor 010 dans le premier cas: le bit MSB n'est pas défini pour les deux valeurs de la plage.Si vous voulez maximiser cela, ce que nous devons faire est de garder le MSB de 5 (100) tel qu'il est et de réfléchir à maximiser les bits inférieurs restants. Comme nous savons que les bits inférieurs seront tous un pour le cas où tout est 11, ce qui n'est que 3, c'est-à-dire 2 ^ 2-1. Puisque le problème parle de la plage entre 2 et 5, nous en avons certainement 3 dans la plage. Donc, tout ce que nous devons faire est de trouver l'ensemble MSB le plus élevé dans la plus grande des 2 valeurs et d'ajouter les 1 restants pour les bits inférieurs.
deuxième cas: Comme dans le cas où MSB est défini pour les deux valeurs de la plage, xor aura définitivement ces bits définis comme 0 et nous devons revenir aux bits inférieurs. Encore une fois pour les bits inférieurs, nous devons répéter la même logique que le premier cas. exemple: (10, 12) (1010, 1100) Comme vous pouvez le voir, les deux MSB sont définis sur 1, nous devons donc revenir aux bits inférieurs qui sont 010 et 100. Maintenant, ce problème est le même que dans le premier cas.
Il existe plusieurs façons de coder cela. Ce que j'ai fait, c'est de faire juste le xor entre «petit» et «haut» et cela supprimera le bit MSB si les bits «petit» et «haut» ont un bit MSB défini. Dans le cas contraire, il conservera le bit MSB. Après cela, j'essaie de faire tous les bits inférieurs 1 en trouvant la puissance maximale de 2 dans la sortie xorée et en soustrayant de 1.
la source
Eh bien, vous pouvez utiliser le XOR de l et r pour trouver la réponse.
Supposons que l = 4 et r = 6.
l = 100, r = 110 (équivalents binaires de ces nombres)
l⊕r = 0 10
Cela signifie que la valeur maximale que vous recherchez aura certainement son premier bit (MSB) à zéro. (Pensez-y, est-il même possible que votre valeur maximale ait un 1 dans le premier bit? Si c'était 01010 et 00101, le xor aurait été = 01 111, c'est-à-dire que la valeur maximale entre 01010 et 00101 aura certainement un 1 dans leur deuxième bit de gauche, il n'est pas possible d'obtenir un 1 avant le deuxième bit de gauche c'est-à-dire dans le premier bit de gauche)
Il vous reste donc les 2 bits restants pour trouver le maximum. Nous savons que la valeur maximale possible lorsque nous avons n bits avec nous est = 2 n -1, donc la réponse dans ce cas sera 2 2 -1 = 4-1 = 3.
À partir de l'exemple ci-dessus, nous pouvons faire un algorithme général pour cela.
Étape 1. num = nombre de bits requis pour représenter max ( l , r )
Étape 2. res = l ⊕ r
Étape 3. pos = position du premier bit qui est défini à partir de la gauche dans res (indexation basée sur 0)
Étape 4. n = num - pos
Étape 5. ans = 2 n −1
Complexité temporelle = O (n)
la source
Pour chaque chiffre binaire, il existe 4 possibilités: 1_and_1, 1_and_0, 0_and_1 ou 0_and_0. Les chiffres inférieurs possibles ne font pas ou peu de différence dans la sortie xor de choix du chiffre suivant. Le meilleur algorithme possible est d'ignorer tous les chiffres inférieurs et de ne considérer que les 2 suivants disponibles, étant donné les choix précédents concernant les chiffres supérieurs. S'il s'agit de 1_and_1 ou 0_and_0, le choix est clair, mais si ce chiffre est 1_and_0 vs 0_and_1 (qui ont une valeur xor mais inégale), alors de manière récursive, il devrait être égal à l' algorithme https://en.wikipedia.org/wiki/Edit_distance , ce qui signifie le pire cas de journal au carré.
la source
Pour les intervalles de 32 bits, je suis juste tombé sur cette
O(1)
solution sur les éditoriaux de Hacker Rank. Je n'ai aucune idée de comment cela fonctionne, mais cela fonctionne. (Peut-être que quelqu'un peut expliquer pourquoi cela fonctionne.)Source: https://www.hackerrank.com/challenges/maximizing-xor/editorial
la source