Dies wurde von mir in einem Interview verlangt und dies ist die Lösung, die ich bereitgestellt habe:
public static int[] merge(int[] a, int[] b) {
int[] answer = new int[a.length + b.length];
int i = 0, j = 0, k = 0;
while (i < a.length && j < b.length)
{
if (a[i] < b[j])
{
answer[k] = a[i];
i++;
}
else
{
answer[k] = b[j];
j++;
}
k++;
}
while (i < a.length)
{
answer[k] = a[i];
i++;
k++;
}
while (j < b.length)
{
answer[k] = b[j];
j++;
k++;
}
return answer;
}
Gibt es einen effizienteren Weg, dies zu tun?
Bearbeiten: Methoden mit korrigierter Länge.
while (i < a.length && j < b.length) answer[k++] = a[i] < b[j] ? a[i++] : b[j++];
Java-Sprachspezifikation: Bedingter Operator? : .Antworten:
Eine kleine Verbesserung, aber nach der Hauptschleife können Sie
System.arraycopy
das Ende eines der Eingabearrays kopieren, wenn Sie am Ende des anderen angelangt sind. Dies ändert jedoch nichts an denO(n)
Leistungsmerkmalen Ihrer Lösung.quelle
Ist etwas kompakter aber genau gleich!
quelle
Ich bin überrascht, dass niemand diese viel coolere, effizientere und kompaktere Implementierung erwähnt hat:
Punkte von Interessen
System.arraycopy
würden Versionen mit gewinnen, da dies intern mit einer einzelnen x86-Assemblyanweisung möglich ist.a[i] >= b[j]
statta[i] > b[j]
. Dies garantiert "Stabilität", die definiert ist als wenn Elemente von a und b gleich sind, wir wollen Elemente von a vor b.quelle
j < 0
,b
ist bereits erschöpft, so dass wir weiterhin die restlichena
Elemente zumanswer
Array hinzufügenAlle Verbesserungen, die vorgenommen werden könnten, wären Mikrooptimierungen. Der Gesamtalgorithmus ist korrekt.
quelle
System.arrayCopy()
ist dumm schnell, da es CPU-optimiertememcpy
Aufrufe verwendet. Es besteht also die Möglichkeit, die Leistung durch Kopieren von Blöcken zu verbessern. Es gibt auch Möglichkeiten für die binäre Suche nach den Grenzen.Diese Lösung ist auch anderen Posts sehr ähnlich, außer dass sie System.arrayCopy verwendet, um die verbleibenden Array-Elemente zu kopieren.
quelle
Hier ist die Funktion aktualisiert. Es werden Duplikate entfernt, hoffentlich findet jemand dies verwendbar:
quelle
Dies kann in 4 Anweisungen wie folgt erfolgen
quelle
sort
Funktion sich nicht als Sortiermethode verwenden kann. Das wäre unendliche Regression statt Rekursion. Die andere Voraussetzung ist auch, dass merge_array die Funktion ist, die sort implementiert. Daher ist diese Antwort im wahrscheinlichsten Zusammenhang unbrauchbar.Ich musste es in Javascript schreiben, hier ist es:
quelle
Apache-Sammlungen unterstützen die Sortiermethode seit Version 4; Sie können dies mit der folgenden
collate
Methode tun :Hier Zitat aus Javadoc:
Das Rad nicht neu erfinden! Dokumentreferenz: http://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html
quelle
GallopSearch Merge: O (log (n) * log (i)) statt O (n)
Ich ging voran und implementierte den Vorschlag von Greybeard in den Kommentaren. Vor allem, weil ich eine hocheffiziente geschäftskritische Version dieses Codes brauchte.
Dies sollte der effizienteste Weg sein, mit einer zeitlichen Komplexität von O (log (n) * log (i)) anstelle von O (n). Und Worst-Case-Zeitkomplexität von O (n). Wenn Ihre Arrays klumpig sind und lange Werteketten zusammen haben, wird dies jede andere Möglichkeit in den Schatten stellen, andernfalls ist es einfach besser als sie.
Es hat zwei Lesewerte am Ende des Zusammenführungsarrays und den Schreibwert innerhalb des Ergebnisarrays. Nachdem herausgefunden wurde, welcher Endwert geringer ist, wird eine Galoppsuche in diesem Array durchgeführt. 1, 2, 4, 8, 16, 32 usw. Wenn der Bereich gefunden wird, in dem der Lesewert des anderen Arrays größer ist. Es sucht binär in diesen Bereich (halbiert den Bereich, sucht die richtige Hälfte, wiederholt bis zum Einzelwert). Dann kopiert es Array diese Werte in die Schreibposition. Beachten Sie, dass die Kopie notwendigerweise so verschoben wird, dass sie nicht dieselben Werte aus beiden Lesearrays überschreiben kann (was bedeutet, dass das Schreibarray und das Lesearray identisch sein können). Es führt dann dieselbe Operation für das andere Array aus, von dem jetzt bekannt ist, dass es kleiner als der neue Lesewert des anderen Arrays ist.
Dies sollte der effizienteste Weg sein, dies zu tun.
Einige Antworten hatten eine doppelte Entfernungsfähigkeit. Dies erfordert einen O (n) -Algorithmus, da Sie tatsächlich jedes Element vergleichen müssen. Hier ist also eine eigenständige Anwendung, die nachträglich angewendet werden kann. Sie können nicht durch mehrere Einträge galoppieren, wenn Sie sich alle ansehen müssen, obwohl Sie durch die Duplikate galoppieren könnten, wenn Sie viele davon hätten.
Update: Vorherige Antwort, kein schrecklicher Code, aber deutlich schlechter als oben.
Eine weitere unnötige Hyperoptimierung. Es ruft nicht nur Arraycopy für die Endbits auf, sondern auch für den Anfang. Verarbeiten einer einleitenden Nichtüberlappung in O (log (n)) durch eine binäre Suche in den Daten. O (log (n) + n) ist O (n) und in einigen Fällen ist der Effekt ziemlich ausgeprägt, insbesondere wenn es überhaupt keine Überlappung zwischen den zusammengeführten Arrays gibt.
quelle
That is totally what the implemented Arrays.sort does
( Das : aus der ersten Überarbeitung Ihrer Antwort - oder - aus meinem Kommentar vom 19. Februar?) - kann auch in Sunsofts JDK 8 nicht gefunden werden: Auf welche Implementierung vonArrays.sort
beziehen Sie sich?Hier ist eine gekürzte Form in Javascript geschrieben:
quelle
quelle
a[mid+1 .. hi]
aufaux
für?Ich denke, die Einführung der Überspringliste für das größere sortierte Array kann die Anzahl der Vergleiche verringern und den Kopiervorgang in das dritte Array beschleunigen. Dies kann gut sein, wenn das Array zu groß ist.
quelle
quelle
quelle
for (int i, j, k = i = j = 0 ; k < c.length ; ) c[k++] = b.length <= j || i < a.length && a[i] < b[j] ? a[i++] : b[j++];
. Wie unterscheidet es sich von Andrews Antwort von 2014 ?Der Algorithmus könnte auf viele Arten verbessert werden. Zum Beispiel ist es sinnvoll zu prüfen, ob
a[m-1]<b[0]
oderb[n-1]<a[0]
. In keinem dieser Fälle müssen weitere Vergleiche durchgeführt werden. Der Algorithmus könnte einfach Quell-Arrays in der resultierenden Reihenfolge in der richtigen Reihenfolge kopieren.Kompliziertere Verbesserungen können das Suchen nach verschachtelten Teilen und das Ausführen eines Zusammenführungsalgorithmus nur für diese umfassen. Dies kann viel Zeit sparen, wenn sich die Größen der zusammengeführten Arrays mehrmals unterscheiden.
quelle
Dieses Problem hängt mit dem Mergesort-Algorithmus zusammen, bei dem zwei sortierte Unterarrays zu einem einzigen sortierten Unterarray kombiniert werden. Das CLRS- Buch enthält ein Beispiel für den Algorithmus und beseitigt die Notwendigkeit, zu überprüfen, ob das Ende erreicht wurde, indem am Ende jedes Arrays ein Sentinel-Wert (etwas, das vergleichbar und "größer als jeder andere Wert" ist) hinzugefügt wird.
Ich habe dies in Python geschrieben, aber es sollte sich auch gut in Java übersetzen lassen:
quelle
Sie können 2 Threads verwenden, um das resultierende Array zu füllen, einen von vorne und einen von hinten.
Dies kann bei Zahlen ohne Synchronisation funktionieren, z. B. wenn jeder Thread die Hälfte der Werte einfügt.
quelle
quelle
quelle
quelle
Meine Lieblingsprogrammiersprache ist JavaScript
quelle
Verwenden Sie möglicherweise System.arraycopy
quelle
Ausgabe ist:
1, 2, 3, 4, 5, 6, 8, 9, 10, 100, 999, 1001,
quelle
arr2
nichtind2
, abertemp
.Sie können ternäre Operatoren verwenden, um den Code etwas kompakter zu gestalten
quelle
Nur ein kleiner Unterschied zur ursprünglichen Lösung
quelle
Um zwei sortierte Arrays in der O (m + n) -Zeitkomplexität zusammenzufassen, verwenden Sie den folgenden Ansatz mit nur einer Schleife. m und n ist die Länge des ersten Arrays und des zweiten Arrays.
quelle
quelle
Da die Frage keine bestimmte Sprache annimmt. Hier ist die Lösung in Python. Angenommen, die Arrays sind bereits sortiert.
Ansatz 1 - Verwenden von Numpy-Arrays: Importieren Sie Numpy
Ansatz 2 - Verwenden der Liste unter der Annahme, dass die Listen sortiert sind.
quelle
Since the question doesn't assume any specific language
vom 2011/5/11/19: 43 ist es mit Java getaggt ..sort()
istO(n log n)
bestenfallsHier ist meine Java-Implementierung, die Duplikate entfernt.
quelle