Angenommen, die Intervalle sind als (a1,b1), ..., (an,bn)
angegeben. Erstellen Sie ein sortiertes Array der Länge 2n
, bei dem Bindungen durch
ai = aj
, dann ai
zuerst setzen iff bi < bj
bi = bj
, dann bi
zuerst setzen iff ai < aj
ai = bj
, dann setze ai
first Markiere jeden Punkt als a
oder b
(behalte vielleicht ein binäres Array der Länge 2n
, um dies zu tun). Gehen Sie durch die Arrays, wobei Sie verfolgen, wie viele Intervalle den gegebenen Punkt berühren (laufende Summe von a
s minus laufende Summe von b
s). Die maximal gefundene Anzahl tritt in dem Intervall mit der größten Überlappung auf.
Dies ist O(n log n)
aufgrund der Sortierung der Intervalle.
Wenn die Werte ai und bi keine kleinen ganzen Zahlen & lt; N können sie dann durch Sortieren der Indizes in der Liste aller unterschiedlichen ai- und bi-Werte reduziert werden.
Gegeben die Eingabe "list", die alle eindeutigen ai und bi enthält. Der sortierte Index befindet sich in C #:
int [] index = Enumerable.Range (0, Liste.Zahl) .OrderBy (i = & gt; Liste [i]). ToArray ();
Durch Invertierung dieser Permutation kann jedem ai und bi ein Wert von 0 bis N - 1 zugewiesen werden.
int [] Werte = invertPermutation (Index);
ai kann durch Werte [location_of_ai_in_List]
ersetzt werdenNun, da das neue ai und bi hergestellt werden kann & lt; N gibt es einen netten Trick, um das maximale überlappende Intervall in O (N) zu finden, sowie einige andere Fragen können schnell beantwortet werden.
deklariert ein Array von N + 1 Elementen:
int [] Summe = neu int [N + 1];
für jedes Intervall ausführen:
sum [ai] ++;
Summe [bi + 1] -;
// Die Gesamtkomplexität dieses Schrittes ist O (N), da wir jedes Intervall in O (1) verarbeiten.
Aggregat:
für (int i = 1; i & lt; = N; i ++) { Summe [i] + = Summe [i - 1]; }
// Dies ist ein O (N) Schritt.
Dieses Intervall [ai, bi] ist eine Lösung und die Häufigkeit, mit der es alle anderen Intervalle schneidet, ist "sum [k] - 1" (nicht für sich selbst verantwortlich).
Ein alternativer Ansatz für Intervallbäume, der geeignet sein kann, wenn ai, bi kleine ganze Zahlen sind (z. B. vielleicht 16-Bit-Zahlen), ist:
Der Wert von x bei der Iteration gibt die Anzahl der Intervalle an, die den Punkt j schneiden, so dass der größte Wert den Punkt ergibt, der die meisten Intervalle schneidet.
Dies dauert O (N + n) Zyklen, also ist es nur nützlich, wenn n & gt; N für Ihre Anwendung.
(Streng genommen beantwortet dies die Frage nicht, da sie den Punkt findet, der am meisten schneidet. Sie sollten jedoch in der Lage sein, diesen Ansatz zu erweitern, um das Intervall zu finden, das am meisten schneidet.)
Tags und Links algorithm data-structures