eine sortierte Array von ganzen Zahlen Gegeben mit möglicherweise dupliziert, wie Sie einen Index i
so finden Sie, dass A[i]=i
Finding A [i] = i in einem sortierten Array mit Dubletten
Dies ist ein Problem in einem der Programmierbücher, die ich lese (Cracking the code interview). Die Lösung wird wie folgt umrissen:
public static int magicFast(int[] array, int start, int end) {
if (end < start || start < 0 || end >= array.length) {
return -1;
}
int midlndex = (start + end)/2;
int midValue = array[midlndex];
if (midValue == midlndex) {
return midlndex;
}
/* Search left */
int leftlndex = Math.min(midlndex - 1, midValue);
int left = magicFast(array, start, leftlndex);
if (left >= 0) {
return left;
}
/* Search right */
int rightlndex = Math.max(midlndex + i, midValue);
int right = magicFast(array, rightlndex, end);
return right;
}
Der Autor äußert sich nicht zur Zeitkomplexität. Dies scheint jedoch eine O (n) -Lösung zu sein, da wir beide Seiten des "mittleren" Punktes betrachten müssen, im Gegensatz zu dem Problem, bei dem Array-Elemente verschieden sind. Die Rekursionsbeziehung ist T (n) = 2T (n/2) + c (c - konstante Zeit, um zu prüfen, ob das mittlere Element die Antwort ist)
Wie ist das besser als ein einfacher linearer Scan dann? Dies erscheint übermäßig kompliziert, nur um lineare Zeiteffizienz zu erreichen. Fehle ich hier etwas?
@HenkHolterman: Wenn 'links <<0, dann geht der Algorithmus weiter zur Suche nach rechts. Also, im schlimmsten Fall, durchsucht es beide Seiten des Arrays im Gegensatz zu einer typischen binären Suche, die sicherstellt, dass nur eine Hälfte des Arrays betrachtet wird, oder? – Bugaboo
Ja, es ist etwas komplizierter als bei einer normalen binären Suche. Ich habe diesen Teil falsch gelesen. –
Wenn der Schwerpunkt nicht auf dem Worst-Case-Verhalten liegt, ist dies immer noch besser als ein einfacher linearer Scan, da er oft sublinear ausgeführt werden kann. – pjs