Effizientes Ermitteln der Anzahl kleinerer Elemente für jedes Element in einem Array


9

Ich bin bei diesem Problem festgefahren:

Wenn ein Array der ersten zufällig permutierten natürlichen Zahlen gegeben ist, wird ein Array so konstruiert, dass die Anzahl der Elemente von bis die kleiner als . AB B ( k ) A ( 1 ) A ( k - 1 ) A ( k )nBB(k)A(1)A(k1)A(k)

i) Kannst du bei gegebenem in Zeit finden? ii) Kannst du bei gegebenem in Zeit finden?B O ( n ) B A O ( n )ABO(n)
BAO(n)

Hier ist . Ein konkretes Beispiel: | A 8 4 3 1 7 2 9 6 5 B 0 0 0 0 3 1 6 4 4 |B(1)=0

|A843172965B000031644|

Kann mir jemand helfen? Vielen Dank.


Ich fand dies: Berechnen von Permutationscodierungen, die -Algorithmen für diese Probleme liefern. Zumindest denke ich, dass es die gleichen Probleme sind. O(nlogn)
Realz Slaw

@Merbs bedeutet dieser Hinweis, den Sie gegeben haben, dass Sie eine Lösung haben?
AJed

1
@AJed, es bedeutet, dass ich einen Algorithmus habe, obwohl es für den einfachen Algorithmus ohne Leerzeichen und braucht, wenn wir Speicherplatz haben. Im Moment neige ich dazu, in weder nicht möglich zu sein, noch beide den gleichen Algorithmus zu verwenden. O ( n log n ) O ( n )O(n2)O(nlogn)O(n)
Merbs

@Merbs. Ich denke, Ihr Hinweis kann zum richtigen Weg führen. Ich habe auch eine Lösung (nach Ihrem Hinweis). Ich denke, es gibt einen Trick in der Analyse, der dazu führt, dass es zu . Ich denke, der Trick ist das Wissen, dass von 1: geht . A nO(n)An
AJed

2
In diesem Artikel wird auch ein -Algorithmus angegeben. Sind Sie sicher, dass es dafür einen -Algorithmus gibt? O ( n )O(nlogn)O(n)
Realz Slaw

Antworten:


1

Der naive Algorithmus zur Bestimmung von aus :A.BA

Bestimmen Sie für den Wert von indem Sie jedes mit für und diejenigen zählen, die erfüllen .B ( k ) A ( i ) A ( k ) i = 1 , ... , k A ( ik=1,,nB(k)A(i)A(k)i=1,,kA(i)<A(k)

Dieser Algorithmus vergleicht mit allen anderen ( mal), mit anderen usw., sodass die Gesamtzahl der Vergleiche beträgt. . Aber das ist nicht das Beste, was wir tun können. Wenn wir zum Beispiel , müssen wir keine Vergleiche anstellen! da es sich um die ersten natürlichen Zahlen handelt und garantiert ist (unabhängig von der Permutation), dass die niedrigeren natürlichen Zahlen vorhanden sind. Was ist mit ? Anstatt bis prüfen, könnten wir auch prüfen . Das ist:A(1)n1A(2)n2(n1)(n2)2B(n)B(n)=A(n)1 nn1B(n1)A(1)A(n2)A(n)

Verwenden Sie für den obigen Algorithmus. Verwenden Sie für den umgekehrten Algorithmus: Bestimmen Sie indem Sie ihn zunächst auf und dann für jeden Eintrag für subtrahieren , das ist kleiner als .k=1,,n2k=n2,,nB(k)A(n)11A(i)i=k+1,,nA(k)

Dies würde Schritte, was immer noch . Beachten Sie auch, dass bei der Konstruktion von aus , wenn ist, .2×(n21)(n22)2=(n2)(n4)4O(n2)ABB(n)=A(n)1A(n)=B(n)+1

Aber jetzt zu mehr Finesse. Wenn wir zusätzlichen Platz oder eine Sortierung an Ort und Stelle haben, können wir die Zahlen sortieren, während wir sie vergleichen. Zum Beispiel:

|A843172965S987432165B0000316|

Anstatt alle zu überprüfen (oder sie in der richtigen Reihenfolge zu überprüfen), könnten wir die binäre Suche verwenden, um jedes zu bestimmen . Die Sortierung benötigt jedoch noch Zeit .B(k)O(nlogn)


Dies war nur meine erste Idee; obwohl mir klar ist, dass das Problem interessanter ist, als ich es ursprünglich anerkannt habe. Und ich hatte noch keine Gelegenheit, die Ergebnisse von Realz Slaw zu lesen, sodass der Algorithmus möglicherweise nicht funktioniert.
Merbs

0

Anstatt jedes einzeln zu bestimmen , können wir vorausschauend sein und jede Zahl in einmal durchgehen ! Aber wir werden Leerzeichen verwenden:B(k)A n

|A123456789B800000000104000011112030001222230101123333407011233345320123444561901234445666012344567450123456784|

Wir könnten noch mehr Zeit sparen, indem wir die bereits ermittelten nicht aktualisieren (dh es macht keinen Sinn, nach dem ersten Schritt zu aktualisieren), aber im schlimmsten Fall müssen wir mal8(n)(n+2)2


0

Sowohl I als auch II sind mit #next_greater_element lösbar, das ich hier erklärt habe . Aber es ist etwas schwieriger als nur das Problem, aber vor der Lösung müssen Sie das nächst größere Element lernen:

  1. Nehmen wir an, wir haben einen Vektor für jedes Element von nennen es für Element . nun einmal den nächsten größeren Algorithmus von rechts nach links laufen , aber ausgehend außer Einstellelement in den nächsten größeren Elementindex eindrücken die Elemente , die ihre nächstes größer ist element.then iterieren über das Array links nach rechts und dann wobei die Größe des Vektors und seines da jeder der nächstgrößere Algorithmus und auch Iteration istS i i i A S i i B [ i ] = x j = 0 ( S i [ j ] + 1 ) x S i Θ ( n ) Θ ( n ) Θ ( n )ASiiiASiiB[i]=j=0x(Si[j]+1)xSiΘ(n)Θ(n)Θ(n)

Der zweite Teil ist ähnlich und stellt fest, dass wir den Wert des am besten geeigneten Elements in EDIT erhalten können: Meine Lösung ist falsch, es scheint, dass es keine -Lösung gibto ( n )O(1)o(n)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.