2010-10-28 8 views
7

Mögliche Duplizieren:
Quickest way to find missing number in an array of numbersTricky Algorithmus Frage

Input: unsortierten Array A [1, .., n], die 0 alle bis auf eine der ganzen Zahlen im Bereich enthält, ..

Das Problem besteht darin, die fehlende ganze Zahl in O (n) Zeit zu bestimmen. Jedes Element von A ist binär dargestellt, und die einzige verfügbare Operation ist das Funktionsbit (i, j), das den Wert des j-ten Bits von A [i] zurückgibt und konstante Zeit benötigt.

Irgendwelche Ideen? Ich denke, dass ein Algorithmus zum Teilen und Herrschen richtig wäre, aber ich kann mir nicht vorstellen, was genau ich tun sollte. Danke im Voraus!

+5

n (n + 1)/2 - Summe;) – AraK

+0

Wenn Bit (i, j) die EINZIGE verfügbare Operation ist, wie schlagen Sie vor, einen Divide-and-Conquer-Algorithmus zu implementieren? –

+0

@A. Rex: der mögliche Täter, den du verlinkt hast, hat nicht die gleiche Beschränkung auf Anweisungen, also denke ich nicht, dass es notwendigerweise ein Betrogener ist. –

Antwort

9

Es ist eine mathematische Eigenschaft, dass die Summe der Zahlen zwischen 1 und n wo nn(n+1)/2 ist. Sie können dies für 10 sehen:

1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 
= (1+10) + (2+9) + (3+8) +(4+7) + (5+6) 
= 11 + 11 + 11 + 11 + 11 
= 55 

Also, durch die Erweiterung, ist die Summe der Zahlen 0-n da Sie nur 0 bis es das Hinzufügen sind. Also, was Sie tun, ist, addieren Sie alle Zahlen und behalten Sie eine Zählung bei, dann verwenden Sie diese Formel, um die fehlende herauszufinden.

Also, so etwas wie:

count = 0 
sum = 0 
foreach num in list: 
    sum = sum + num 
    count = count + 1 
missing = count * (count+1)/2 - sum 

die Zahl mit bit(i,j) bekommen ist schwierig, so dass Sie die Bits einzeln extrahieren müssen werden und sie in tatsächliche Zahlen zum Summieren.

+0

Dies liest alle n log n Bits von A, also dauert es n log n Zeit. –

+1

@Reid: Nein, es ist überhaupt nicht log n. Sie können n nicht sowohl für die Anzahl der Bits als auch für die Anzahl der ganzen Zahlen verwenden. Die Anzahl der Bits in einer Ganzzahl ist _constant_, so dass es effektiv "O (32n)" (für eine 32-Bit-Zahl) ist, was genau dasselbe ist wie "O (n)". – paxdiablo

+0

Ich bin ziemlich sicher, wenn das OP schreibt "Integer", sie bedeuten "Integer", nicht "Ganzzahl kleiner als 2^32". Sonst gibt es nur endlich viele mögliche Eingaben, es macht also keinen Sinn über asymptotische Laufzeit überhaupt zu sprechen. Offensichtlich ist die Länge einer tatsächlichen mathematischen Ganzzahl in Bits nicht konstant. –

0

Es ist eine Trick Frage dann, da die Verwendung der Bit-Methode würde nur erfordern, dass Sie jedes Bit für jede Zahl, was bedeutet, es würde automatisch zu O (n * j) wo j ist die Anzahl der Bits, die n darstellt.

Ich denke, Paxdiablo hat es, vorausgesetzt, Sie haben eine Lösung, die nicht die Bit-Methode verwendet.

+3

Neil, das wäre immer noch technisch "O (n)", da "j" eine Konstante ist. – paxdiablo

+0

j ist in der Praxis konstant, weil die Länge einer Ganzzahl oder Lang immer gleich ist, jedoch die signifikanten Stellen von j um eins mit n * 2 inkrementieren, wobei n> 0 ist. Mehr wie O (log n). – Neil

6

Sie könnten XOR-Operator als schneller als Zugabe verwenden. Da Sie Zugriff auf jedes Bit haben, machen Sie hier ein bitweises XOR. Das Prinzip hier verwendet werden soll (A XOR B XOR A) = B

zB: (1 XOR 2 XOR 3) XOR (1 XOR 2) = 3

for i=0 to n 
{ 
Total=Total XOR i 
} 

foreach element in A 
{ 
Total=Total XOR element 
} 
+0

Eigentlich ist das ziemlich schlau, +1. Sie können nicht sicher sein, dass XOR schneller als Addition ist, aber es ist eine saubere Modifikation der Zwei-Most-/Eins-zu-Eins-Variante (z. B. 91 91 82 82 73 64 64 55 55), die XOR verwendet um den Singleton zu finden. – paxdiablo

+1

Xor wird niemals langsamer sein als Addition ... Warum: Außerdem gibt es ein Übertrags-Bit, das einen Volladdierer erfordert, der einen Schritt hinzufügt ... Es wird mit parallelen Addierern in moderner Architektur eliminiert, die fast die gleiche Leistung (xor uses) hat 1 Tor weniger bei dieser Operation) – Mulki

+0

Es gibt eine O (1) -Formel für XOR von 1 bis n. http://stackoverflow.com/questions/3932346/direct-formula-for-summing-xor. XOR vermeidet auch Überlaufprobleme. –