2016-07-02 14 views
-1

Die Längste zunehmende Untersequenz Problem ist es, eine Untersequenz einer gegebenen Sequenz zu finden, in der die Untersequenzelemente in sortierter Reihenfolge sind und in der die Untersequenz so lang wie möglich ist.Längste Erhöhung der Untersequenz-Optimierung

Hier ist mein O (n^2) Ansatz, der für lange Eingabe sehr langsam ausgeführt wird:

N = int(input()) 

lst = [] 
for i in range(N): 
    lst.append(input()) 

count = [1] * N 

for i in range(1, len(lst)): 
    for j in range(i): 
     if(int(lst[j]) < int(lst[i])): 
      k = int(count[j]) + 1 
      if (k > int(count[i])): 
       count[i] = k 
count.sort() 
print(count[-1]) 

Kann mir jemand sagen, wie es in O getan werden kann (n * log n) Zeit?

+1

Wenn ich für den Algorithmus gesucht, der * erste * DuckDuckGo Ergebnis war [Wikipedia] (https://en.wikipedia.org/wiki/Longest_increasing_subsequence), die einen Algorithmus hat * geschrieben in Python-ähnliche Sprache * ... – Djizeus

+1

Und wenn Sie eine Video-Erklärung benötigen: https://www.youtube.com/watch?v=S9oUiVYEq7E&t=0s –

+0

Siehe auch: [Wie die längste zunehmende Teilsequenz mit dynamischer Programmierung zu bestimmen?] (Http: //stackoverflow.com/questions/2631726/how-to-determine-the-longest-creasing-subsequence-use-dynamic-programming) – Djizeus

Antwort

2

Große Ressourcen wurden in den Kommentaren erwähnt; Wenn Sie immer noch ein Stück Python-Code haben wollen, habe ich es hier geschrieben und erklärt.

In diesem Algorithmus, für alle L < N, verfolgen wir die Werte in der Eingabe, die den Endpunkt der aktuell am längsten wachsenden Untersequenz der Länge L darstellen.

longest_sequence_values speichert diese Werte. Zum Beispiel ist longest_sequence_values[3] ein Wert in der Eingabe, bei dem die am längsten zunehmende Untersequenz der Länge 3 endet.

Beachten Sie, dass longest_sequence_values immer nicht abnehmend ist, was uns erlaubt, eine binäre Suche durchzuführen, wenn wir versuchen, eine neue am längsten wachsende Untersequenz zu erstellen. Dies geschieht, weil der Endpunkt einer Untersequenz der Länge i nicht größer als der Endpunkt einer Untersequenz der Länge j sein kann, wenn i < j.

longest_current_sequence ist die Länge der längsten bisher gefundenen Teilsequenz. Wir benötigen diesen Wert, um den Bereich der binären Suche anzugeben. Es ist auch die Antwort am Ende.

from math import ceil 
N = int(input()) 

input_vals = [] 
for i in range(N): 
    input_vals.append(input()) 

longest_sequence_values = [None] * (N+1) 
longest_current_sequence = 0 

for i in range(N): 
    # binary search starts here 
    # this gives us the log(N) factor 
    lo = 1 
    hi = longest_current_sequence 
    while lo <= hi: 
     mid = int(ceil((lo+hi)/2)) 
     if longest_sequence_values[mid] <= input_vals[i]: 
      lo = mid + 1 
     else: 
      hi = mid - 1 

    # lo will be length of the longest sequence ending at input_vals[i] 
    longest_len_here = lo 
    # We have a new lis of length longest_len_here ending at index i 
    # Note that before we perform the following substitutions, 
    # longest_sequence_values[longest_len_here] >= input_vals[i] 
    # This means that the new endpoint of the lis of length longest_len_here 
    # is <= to the old endpoint. 
    # This point is essential in keeping the result optimal 
    longest_sequence_values[longest_len_here] = input_vals[i] 

    if longest_len_here > longest_current_sequence: 
     longest_current_sequence = longest_len_here 

print longest_current_sequence 
+0

Dein Code läuft perfekt. Hier ist mein Code, es funktioniert gut für einige Eingaben, aber für einige ist es nicht. Es hat einen Fehler, kannst du mir sagen, wo ich es falsch mache. http://paste.ofcode.org/WFqZYpE2e2av4KwhpfSV74 – Atinesh

+0

@Atinesh Können Sie einige Eingaben posten, für die es fehlschlägt? Idealerweise sollte "tailTable" mit Indizes im Bereich "[1, N]" statt mit "[0, N]" arbeiten. Dies liegt daran, dass die Indizes Längen der Größe "1..N" repräsentieren und die Dinge auf diese Weise intuitiver werden. Ihre 'binary_search' Methode sieht schwach aus. Aus irgendeinem Grund ist der Startbereich "[-1, N-1]". Die binäre Suche wird verwendet, um einen sortierten Bereich unter Verwendung einer Eigenschaft in zwei Teile zu unterteilen. In diesem Fall ist diese Eigenschaft 'größte' j

+0

Eigentlich habe ich diesen Code auf "Hacker Rank" ausprobiert, sie haben es in 9 Testfällen getestet, von denen nur 2 erfolgreich sind. Hier ist der Testfall 'Input': http://paste.ofcode.org/MTCs4irbBFNNndgAGf3yEk ' Erwartete Ausgabe': 185 – Atinesh