Längste zunehmende Teilfolge
Gegeben eine Eingabe-Sequenz, was ist der beste Weg, um die längste (nicht unbedingt fortlaufend) nicht-abnehmende Folge.
0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 # sequence
1, 9, 13, 15 # non-decreasing subsequence
0, 2, 6, 9, 13, 15 # longest non-deceasing subsequence (not unique)
Ich bin auf der Suche nach den besten Algorithmus. Wenn der code, Python wäre schön, aber alles ist in Ordnung.
InformationsquelleAutor der Frage Jungle Hunter | 2010-10-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich stolperte in diesem problem, und kam mit diesem Python-3-Einführung:
Da es mich einige Zeit um zu verstehen, wie der Algorithmus funktioniert, war ich etwas Ausführlicher mit Kommentaren, und ich werde auch hinzufügen, eine kurze Erklärung:
seq
ist die Eingangs-Sequenz.L
ist eine Zahl: es wird aktualisiert, während das Schleifen über die Sequenz und es bezeichnet die Länge des längsten incresing Teilfolge gefunden, bis zu diesem moment.M
ist eine Liste.M[j-1]
wird auf eine index derseq
hält, dass der kleinste Wert, der verwendet werden könnte (am Ende) zu bauen, eine steigende Teilfolge der Längej
.P
ist eine Liste.P[i]
aufM[j]
woi
ist der index derseq
. In ein paar Worte, es erzählt, die das Vorherige element der Teilfolge.P
wird genutzt, um das Ergebnis am Ende.Wie der Algorithmus funktioniert:
i
.j
lassenseq[M[j]
werden<
alsseq[i]
.P
M
undL
.Hinweis: Die einzigen Unterschiede mit der der wikipedia-Algorithmus sind der offset von 1 in der
M
Liste, und dasX
ist, die hier genanntseq
. Ich auch testen Sie es mit einem leicht verbesserten unit-test-version, die eine zeigte in Eric Gustavson Antwort und es alle tests bestanden.Beispiel:
Am Ende werden wir haben:
Wie Sie sehen
P
ist ziemlich einfach. Wir haben, um es zu betrachten von dem Ende, so dass er erzählt, dass vor60
es gibt40,
vor80
es gibt40
vor40
es gibt20
vor50
es gibt20
und vor20
es gibt10
stoppen.Der komplizierte Teil ist auf
M
. Am AnfangM
war[0, None, None, ...]
seit dem letzten element der Teilfolge der Länge 1 (also position 0 inM
) wurde am index 0:30
.Zu diesem Zeitpunkt werden wir anfangen, looping auf
seq
und schauen10
da10
ist<
als30
M
werden aktualisiert:So, jetzt
M
aussieht:[1, None, None, ...]
. Das ist eine gute Sache, weil10
mehr chanches einen längeren steigende Teilfolge. (Die neue 1 ist der index 10)Jetzt ist es der Wende von
20
. Mit10
und20
wir haben Teilfolge der Länge 2 (index 1 inM
), soM
werden:[1, 2, None, ...]
. (Der neue 2 ist der index von 20)Jetzt ist es der Wende von
50
.50
wird nicht ein Teil von jeder Teilfolge, so ändert sich nichts.Jetzt ist es der Wende von
40
. Mit10
20
und40
haben wir einen sub der Länge 3 (index 2 inM
soM
werden:[1, 2, 4, None, ...]
. (Die neue 4 ist der index von 40)Und so weiter...
Für eine komplette Spaziergang durch den code können Sie kopieren und fügen Sie hier 🙂
InformationsquelleAutor der Antwort Rik Poggi
Hier ist, wie einfach die längste zu-und abnehmende Folge in Mathematica:
Ausgabe:
Mathematica hat auch LongestIncreasingSubsequence Funktion in der Combinatorica` Bibliothek. Wenn Sie nicht über Mathematica können Sie die Abfrage der WolframAlpha.
Quelle: link
Habe ich umgeschrieben, die C++ Implementierung für Java vor einer Weile, und kann bestätigen es funktioniert. Vektor-alternative in python ist die Liste. Aber wenn Sie möchten, testen Sie es selbst, hier ist der link für die online-compiler mit Beispiel-Implementierung geladen: link
Beispiel Daten:
{ 1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7 }
und die Antwort:
1 3 4 5 6 7
.InformationsquelleAutor der Antwort Margus
Hier einige python-code mit tests, die implementiert der Algorithmus läuft in O(n*log(n)). Ich fand diese auf einer der wikipedia-Diskussionsseite über die längsten steigenden Teilfolge.
InformationsquelleAutor der Antwort zzz
Hier ist eine ziemlich Allgemeine Lösung:
O(n log n)
Zeit,list
numpy.array
str
und mehr,key
parameter funktioniert wie in dem builtinsorted
Funktion,Code:
Schrieb ich einen docstring für die Funktion, dass ich nicht fügen Sie oben, um zu zeigen, den code:
Einige Beispiele:
Diese Antwort war zum Teil inspiriert durch die Frage zu Code-Review und zum Teil durch Frage zu Fragen über "out of sequence" Werten.
InformationsquelleAutor der Antwort arekolek
InformationsquelleAutor der Antwort benben
Hier ist der code und die Erklärung mit Java, kann ich hinzufügen, für python bald.
So dass die Länge der LIS 6 (Größe der Liste).
Ausgang für den obigen code: Längsten Steigenden Teilfolge[0, 1, 3, 7, 11, 15]
InformationsquelleAutor der Antwort Deepak Singhvi
Die effizienteste Algorithmus für das O(NlogN) beschrieben hier.
Anderen Weg, um dieses Problem zu lösen ist, um die längste gemeinsame Teilfolge (LCS) des ursprünglichen Arrays erstellt und es ist sortiert-version, die in O(N2).
InformationsquelleAutor der Antwort
hier ist eine kompakte Umsetzung mit "auflisten"
InformationsquelleAutor der Antwort cmantas
Hier ist ein kompakter aber dennoch effiziente Python-Implementierung:
InformationsquelleAutor der Antwort isarandi