Ich glaube, ich habe etwas gefunden, das allgemein und effizient funktionieren sollte, wenn Sie garantiert keine Duplikate haben * (es sollte jedoch auf eine beliebige Anzahl von Löchern und einen beliebigen Bereich von ganzen Zahlen erweiterbar sein).
Die Idee hinter dieser Methode ist wie bei der Quicksort-Methode, bei der wir einen Drehpunkt und eine Trennwand finden und dann auf die Seite (n) mit einem Loch zurückgreifen. Um zu sehen, welche Seiten das Loch haben, ermitteln wir die niedrigsten und höchsten Zahlen und vergleichen sie mit dem Drehpunkt und der Anzahl der Werte auf dieser Seite. Angenommen, der Drehpunkt ist 17 und die Mindestanzahl ist 11. Wenn keine Löcher vorhanden sind, sollten 6 Zahlen vorhanden sein (11, 12, 13, 14, 15, 16, 17). Wenn es 5 gibt, wissen wir, dass es auf dieser Seite ein Loch gibt, und wir können nur auf dieser Seite zurückgreifen, um es zu finden. Ich habe Probleme, es klarer zu erklären. Nehmen wir also ein Beispiel.
15 21 10 13 18 16 22 23 24 20 17 11 25 12 14
Drehpunkt:
10 13 11 12 14 |15| 21 18 16 22 23 24 20 17 25
15 ist der Drehpunkt, angezeigt durch Rohre ( ||
). Es gibt 5 Zahlen auf der linken Seite des Pivots, wie es sein sollte (15 - 10), und 9 auf der rechten Seite, wo es 10 sein sollte (25 - 15). Wir kehren also auf die rechte Seite zurück. Wir werden bemerken, dass die vorherige Grenze 15 war, falls das Loch daneben liegt (16).
[15] 18 16 17 20 |21| 22 23 24 25
Jetzt gibt es 4 Zahlen auf der linken Seite, aber es sollten 5 sein (21 - 16). Wir kehren dort also zurück und notieren erneut die vorherige Schranke (in Klammern).
[15] 16 17 |18| 20 [21]
Die linke Seite hat die richtigen 2 Zahlen (18 - 16), aber die rechte hat 1 anstelle von 2 (20 - 18). Abhängig von unseren Endebedingungen können wir die 1-Zahl mit den beiden Seiten (18, 20) vergleichen und feststellen, dass 19 fehlt oder noch einmal verwendet wird:
[18] |20| [21]
Die linke Seite hat eine Größe von Null, mit einer Lücke zwischen dem Zapfen (20) und der vorherigen Grenze (18), also ist 19 das Loch.
*: Wenn Duplikate vorhanden sind, können Sie diese möglicherweise mithilfe eines Hash-Satzes in O (N) entfernen, wobei die Gesamtmethode O (N) beibehalten wird. Dies kann jedoch mehr Zeit in Anspruch nehmen als die Verwendung einer anderen Methode.