Unter der Annahme, dass mindestens ein Elementpaar die Bedingungen erfüllt und keine Multiplikation von zwei Elementen darin überläuft, kann dies im schlimmsten und besten Fall Theta(n-k)zeitlich und Theta(1)räumlich erfolgen.
auto back_max = a[0];
auto back_min = a[0];
auto best = a[0]*a[k+1];
for(std::size_t i=1; i<n-(k+1); ++i) {
back_max = std::max(back_max, a[i]);
back_min = std::min(back_min, a[i]);
best = std::min(best, std::min(a[i+k+1]*back_max, a[i+k+1]*back_min));
}
return best;
Dies ist hinsichtlich der asymptotischen Worst-Case-Komplexität sowohl für die Zeit als auch für den Raum optimal, da das optimale Produkt mindestens a[0]mit einem der n-(k+1)Elemente in der Entfernung vorliegen kann k+1, sodass mindestens n-(k+1)ganze Zahlen von jedem Algorithmus gelesen werden müssen, der das Problem löst.
Die Idee hinter dem Algorithmus ist wie folgt:
Das optimale Produkt verwendet zwei Elemente von a, vorausgesetzt, diese sind a[r]und a[s]. Ohne Verlust der Allgemeinheit können wir davon ausgehen, dass s > rdas Produkt kommutativ ist.
Aufgrund der Einschränkung abs(s-r) > kimpliziert dies, dass s >= k+1. Nun skönnte jeder der Indizes diese Bedingung erfüllen, also iterieren wir über diese Indizes. Dies ist die Iteration iim angezeigten Code, die jedoch der Einfachheit halber verschoben wird k+1(spielt keine Rolle). Für jede Iteration müssen wir das optimale Produkt mit i+k+1dem größten Index finden und es mit der vorherigen besten Schätzung vergleichen.
Die möglichen Indizes, i+k+1mit denen gepaart werden kann, sind iaufgrund der Abstandsanforderung alle Indizes kleiner oder gleich . Wir müssten auch alle diese Punkte durchlaufen, aber das ist unnötig, da das Minimum von a[i+k+1]*a[j]Over jbei Fix igleich min(a[i+k+1]*max(a[j]), a[i+k+1]*min(a[j]))der Monotonie des Produkts entspricht (wobei das Minimum sowohl in Bezug auf das Minimum als auch das Maximum a[j]für die beiden möglichen berücksichtigt wird Zeichen a[i+k+1]oder gleichwertig die beiden möglichen Richtungen der Monotonie.)
Da die Menge der a[j]Werte, über die wir hier optimieren, gerade ist {a[0], ..., a[i]}und die einfach um ein Element ( a[i]) in jeder Iteration von wächst i, können wir einfach max(a[j])und min(a[j])mit einzelnen Variablen verfolgen , indem wir sie aktualisieren, wenn sie a[i]größer oder kleiner als die vorherigen optimalen Werte sind. Dies erfolgt mit back_maxund back_minim Codebeispiel.
Der erste Schritt der Iteration ( i=0) wird in der Schleife übersprungen und stattdessen als Initialisierung der Variablen ausgeführt.
std::vector? @Scheff - Sortieren würde die ursprünglichen "Distanz" -Beziehungen zerstören.