mit vielen Intervallen [ai, bi], finde ein Intervall, das sich mit der größten Anzahl von Intervallen überschneidet

8

Gegeben viele Intervalle [ai, bi], Finde das Intervall, das die meisten Intervalle schneidet. Können wir das in O (nlogn) oder besser machen? Ich kann nur an einen n ^ 2 Ansatz denken.

    
Peter 12.03.2012, 18:09
quelle

6 Antworten

12

Angenommen, die Intervalle sind als (a1,b1), ..., (an,bn) angegeben. Erstellen Sie ein sortiertes Array der Länge 2n , bei dem Bindungen durch

unterbrochen werden
  • wenn ai = aj , dann ai zuerst setzen iff bi < bj
  • wenn bi = bj , dann bi zuerst setzen iff ai < aj
  • Wenn 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.

    
PengOne 12.03.2012, 23:32
quelle
4

Benutze Intervallbäume: Ссылка .

Wenn Sie einen zentrierten Intervallbaum verwenden, ist die Komplexität O (nlogn + m), wobei m die Gesamtzahl der Schnittpunkte ist (worst case m = n ^ 2).

    
ElKamina 12.03.2012 18:44
quelle
2

Nach der Antwort von PengOne mache ich eine einfache Implementierung, die zwei n-artige Arrays anstelle von 2n-Arrays verwendet.

%Vor%

Code

%Vor%     
Happier 20.03.2012 16:17
quelle
1

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 werden

Nun, 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.

  1. deklariert ein Array von N + 1 Elementen:

    int [] Summe = neu int [N + 1];

  2. 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.

  1. Aggregat:

    für (int i = 1; i & lt; = N; i ++) {     Summe [i] + = Summe [i - 1]; }

// Dies ist ein O (N) Schritt.

  1. finde den Ort k, wo sum [k] maximal ist.
  2. Iteriere die neuen Intervalle [ai, bi] und finde die erste, die die Position k enthält (dh. ai & lt; = k & amp; & k; = bi).

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).

    
RobertB. 18.03.2017 05:53
quelle
0

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:

  1. Machen Sie ein Array A mit N Werten, wobei N größer ist als max (bi)
  2. Löschen Sie alle Werte im Array auf 0
  3. Schleife über die Intervalle und verändere A [ai]: = A [ai] +1, A [bi + 1]: = A [bi + 1] -1
  4. Setzen Sie x = 0
  5. Schlingen Sie über die Array-Berechnung x: = x + A [j] und suchen Sie nach dem größten Wert von x

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.)

    
Peter de Rivaz 12.03.2012 19:29
quelle
-1

Sie können es in n.

tun

[kleinste ai, größte bi]

Also ..

%Vor%     
DanRedux 12.03.2012 18:14
quelle

Tags und Links