{}const=>[]async()letfn</>var
EntwicklungAlgorithmen

Dynamische Programmierung für Dummies: von "was ist das überhaupt?" bis zur Lösung von Interviewaufgaben

Eine verständliche Erklärung der dynamischen Programmierung mit Beispielen in Python und JS. 5 klassische Aufgaben, Schritt-für-Schritt-Lösungsmethode.

К

Kodik

Autor

7 Min. Lesezeit

Was ist dynamische Programmierung in einfachen Worten?

Stellen Sie sich vor, Sie berechnen die Fakultät der Zahl 5.

Dazu benötigen Sie: 5 × 4 × 3 × 2 × 1. Und jetzt werden Sie gebeten, die Fakultät von 6 zu berechnen. Es ist dumm, alles noch einmal zu zählen, oder? Sie wissen bereits, dass 5! = 120, multiplizieren Sie einfach mit 6.

Dynamische Programmierung (DP) - das ist genau der gleiche Ansatz: Wir lösen ein komplexes Problem, indem wir es in Teilaufgaben zerlegen, und Ergebnisse speichern, um dasselbe nicht zweimal zu zählen.

Die Hauptmerkmale der Aufgaben bei der Auftragsvergabe:

🎯 Optimale Unterkonstruktion

Die Lösung eines großen Problems besteht aus Lösungen kleinerer Teilprobleme

🔄 Überlappende Teilaufgaben

Einige Aufgaben wiederholen sich

⚡ Es ist notwendig, das Optimum zu finden

Maximum, Minimum oder Anzahl der Methoden

🔥 100.000+ Schüler sind bereits bei uns

Genug Theorie gelesen?
Zeit zu coden!

Kodik — eine App, in der du durch Praxis programmieren lernst. KI-Mentor, interaktive Lektionen, echte Projekte.

🤖 KI 24/7
🎓 Zertifikate
💰 Kostenlos
🚀 Jetzt starten
Heute beigetreten

Zwei Ansätze für DP: Memo und Tab

1. Auswendiglernen (von oben nach unten)

Dies ist Rekursion + Zwischenspeicherung der Ergebnisse. Wir beginnen mit einer großen Aufgabe und gehen zu den Grundfällen über.

def fibonacci_memo(n, memo={}):
    # Grundfälle
    if n <= 1:
        return n
    
    # Wir überprüfen den Cache
    if n in memo:
        return memo[n]
    
    # Berechnen und speichern
    memo[n] = fibonacci_memo(n-1, memo) + fibonacci_memo(n-2, memo)
    return memo[n]

print(fibonacci_memo(50))  # Sofort!

Wann zu verwenden: wenn die Logik der Aufgabe durch Rekursion intuitiv verständlich ist.

2. Tabulation (von unten nach oben)

Wir erstellen eine Lösungstabelle von den Basisfällen bis zur endgültigen Antwort. Keine Rekursion!

def fibonacci_table(n):
    if n <= 1:
        return n
    
    # Erstellen Sie eine Tabelle
    dp = [0] * (n + 1)
    dp[0] = 0
    dp[1] = 1
    
    # Von unten nach oben ausfüllen
    for i in range(2, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    
    return dp[n]

print(fibonacci_table(50))

Wann zu verwenden: wenn maximale Leistung und Speicherkontrolle erforderlich sind.

Klassische Aufgaben der DV, die man 2026 kennen muss

Aufgabe 1: Fibonacci-Zahlen

Schwierigkeit ohne DP: O(2ⁿ) — exponentiell!
Schwierigkeit mit DP: O(n) - linear!

Wir haben die Lösung bereits oben gesehen. Dies ist eine ideale Aufgabe für den Anfang.

Aufgabe 2: Rucksackproblem (Knapsack Problem)

Sie sind ein Räuber mit einem Rucksack mit einem Fassungsvermögen von W. Es gibt Gegenstände mit Gewicht und Wert. Wie kann man den maximalen Wert nehmen?

def knapsack(weights, values, capacity):
    n = len(weights)
    # dp[i][w] = maximaler Wert für i Artikel und Kapazität w
    dp = [[0] * (capacity + 1) for _ in range(n + 1)]
    
    for i in range(1, n + 1):
        for w in range(1, capacity + 1):
            # Wir nehmen den Gegenstand nicht
            dp[i][w] = dp[i-1][w]
            
            # Wir nehmen den Gegenstand, wenn er hineinpasst
            if weights[i-1] <= w:
                dp[i][w] = max(
                    dp[i][w],
                    dp[i-1][w - weights[i-1]] + values[i-1]
                )
    
    return dp[n][capacity]

weights = [1, 2, 3, 5]
values = [10, 5, 15, 7]
capacity = 7

print(knapsack(weights, values, capacity))  # 32

Anwendung in der Realität: Ressourcenverteilung, Budgetplanung, Optimierung der Serverauslastung.

Aufgabe 3: Längste gemeinsame Teilfolge (LCS)

Finden Sie die längste gemeinsame Teilfolge von zwei Zeilen. Basis für git diff!

def lcs(text1, text2):
    m, n = len(text1), len(text2)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if text1[i-1] == text2[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    
    return dp[m][n]

print(lcs("ABCDGH", "AEDFHR"))  # 3 (ADH)

Anwendung: Versionskontrollsysteme, Plagiatsprüfung, Bioinformatik (DNA-Vergleich).

Aufgabe 4: Münzwechsel

Es gibt Münzen verschiedener Stückelungen. Auf wie viele Arten kann man den Betrag sammeln?

def coin_change(coins, amount):
    # dp[i] = Mindestanzahl von Münzen für den Betrag i
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0  # Für den Betrag 0 benötigen Sie 0 Münzen
    
    for i in range(1, amount + 1):
        for coin in coins:
            if coin <= i:
                dp[i] = min(dp[i], dp[i - coin] + 1)
    
    return dp[amount] if dp[amount] != float('inf') else -1

coins = [1, 2, 5]
amount = 11print(coin_change(coins, amount))  # 3 (5+5+1)

Anwendung: Fintech-Anwendungen, Kassensysteme, Transaktionsoptimierung.

Aufgabe 5: Edit Distance (Levenshtein-Abstand)

Die Mindestanzahl von Operationen, um eine Zeile in eine andere umzuwandeln.

def edit_distance(word1, word2):
    m, n = len(word1), len(word2)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    
    # Initialisierung
    for i in range(m + 1):
        dp[i][0] = i
    for j in range(n + 1):
        dp[0][j] = j
    
    # Ausfüllen der Tabelle
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if word1[i-1] == word2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = 1 + min(
                    dp[i-1][j],    # Entfernung
                    dp[i][j-1],    # Einfügen
                    dp[i-1][j-1]   # Ersatz
                )
    
    return dp[m][n]

print(edit_distance("kitten", "sitting"))  # 3

Anwendung: Korrektur von Tippfehlern, Suchmaschinen, Autovervollständigung.

Schritt-für-Schritt-Methode zur Lösung von Problemen bei der DP

Schritt 1: Finden Sie eine rekursive Lösung

Lösen Sie das Problem zunächst einfach rekursiv, ohne über Optimierung nachzudenken.

# Nicht optimierte Versiondef fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

Schritt 2: Memoisierung hinzufügen

Fügen Sie ein Wörterbuch hinzu, um die Ergebnisse zu speichern.

def fib_memo(n, memo={}):
    if n <= 1:
        return n
    if n not in memo:
        memo[n] = fib_memo(n-1, memo) + fib_memo(n-2, memo)
    return memo[n]

Schritt 3: Konvertieren Sie in Tab (optional)

Übersetzen Sie in einen iterativen Ansatz mit einem Array.

def fib_table(n):
    if n <= 1:
        return n
    dp = [0] * (n + 1)
    dp[1] = 1
    for i in range(2, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    return dp[n]

Schritt 4: Speicher optimieren

Oft kann man O(1) Speicher anstelle von O(n) verwenden.

def fib_optimized(n):
    if n <= 1:
        return n
    prev2, prev1 = 0, 1
    for _ in range(2, n + 1):
        current = prev1 + prev2
        prev2, prev1 = prev1, current
    return prev1

Wichtige Muster der Direktzahlungen im Jahr 2026

1D DP

Eindimensionales Array

  • Fibonacci-Zahlen

  • Climbing Stairs

  • House Robber

2D-DP

Zweidimensionales Array

  • Longest Common Subsequence

  • Edit Distance

  • Knapsack Problem

DP auf Zeilen

Arbeit mit Text

  • Palindrome Subsequences

  • String Matching

  • Wildcard Matching

DP auf Bäumen

Baumstrukturen

  • Binary Tree Maximum Path Sum

  • Diameter of Binary Tree

DP auf Grafen

Graphenalgorithmen

  • Shortest Path (Bellman-Ford)

  • Traveling Salesman Problem

Typische Anfängerfehler

Fehler 1: Sie vergessen die grundlegenden Fälle

def fib(n):
    return fib(n-1) + fib(n-2)
# Endlose Rekursion!

Richtig

def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

Fehler 2: Falsche Tabellengröße

dp = [0] * n
# Wenn Sie Indizes 0..n benötigen,
# Größe n+1 benötigt!

Richtig

dp = [0] * (n + 1)

Fehler 3: Grenzen werden nicht überprüft

if dp[i-1]:
# Was ist, wenn i = 0?

Richtig

if i > 0 and dp[i-1]:

Praktische Tipps für Vorstellungsgespräche.

  1. Zeichnen Sie eine Tabelle auf Papier - Visualisierung hilft, Abhängigkeiten zu finden

  2. Beginnen Sie mit kleinen Beispielen — fib(0), fib(1), fib(2)...

  3. Suchen Sie nach der Rekursionsformel — Wie hängt dp[i] von den vorherigen Werten ab?

  4. Sprechen Sie die Logik laut aus - dies zeigt den Verlauf Ihrer Gedanken

  5. Scheuen Sie sich nicht, zunächst eine suboptimale Lösung zu schreiben - dann kann es verbessert werden

JavaScript-Version für Webentwickler.

Viele Anfänger arbeiten mit JavaScript, daher hier ein Beispiel für JS:

// Speicherfunktion fibMemo(n, memo = {}) {
    if (n <= 1) return n;
    if (memo[n]) return memo[n];
    
    memo[n] = fibMemo(n - 1, memo) + fibMemo(n - 2, memo);
    return memo[n];
}

// Tabulationfunction fibTable(n) {
    if (n <= 1) return n;
    
    const dp = new Array(n + 1).fill(0);
    dp[1] = 1;
    
    for (let i = 2; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    
    return dp[n];
}

// Optimierte Version (O(1) Speicher)function fibOptimized(n) {
    if (n <= 1) return n;
    
    let prev2 = 0, prev1 = 1;
    
    for (let i = 2; i <= n; i++) {
        const current = prev1 + prev2;
        prev2 = prev1;
        prev1 = current;
    }
    
    return prev1;
}

console.log(fibOptimized(50)); // 12586269025

Schlussfolgerung.

Dynamische Programmierung ist keine Magie, sondern ein logischer Ansatz zur Problemlösung. Wichtigste Punkte:

  1. Aufteilen in Unteraufgaben — Finden Sie das Wiederholungsmuster

  2. Speichern Sie die Ergebnisse — nicht doppelt zählen

  3. Beginnen Sie mit der Rekursion — dann optimieren

  4. Trainieren Sie regelmäßig - DP erfordert Übung

Nachdem Sie die dynamische Programmierung gemeistert haben, werden Sie:

✅ Bestehen Sie die meisten technischen Vorstellungsgespräche

✅ Sie können echte Aufgaben in der Produktion optimieren

✅ Sie verstehen, wie viele Bibliotheken und Frameworks funktionieren

✅ Lernen Sie, algorithmisch zu denken

Denken Sie daran: Jeder Algorithmus schien einmal selbst den besten Entwicklern kompliziert zu sein. Hauptsache Übung und Geduld.

Lernen Sie dynamische Programmierung und viele andere wichtige Themen in Kodik – einer Bildungsplattform mit praktischen Kursen für Entwickler. Wir erstellen Inhalte, die bei Vorstellungsgesprächen und bei der Arbeit wirklich helfen!

📱 Und wir haben auch eine coole Telegram-Kanal mit einer freundlichen Community, wo:

  • Wir analysieren die Aufgaben aus den Interviews

  • Wir teilen nützliche Artikel

  • Wir helfen uns gegenseitig zu wachsen

  • Wir diskutieren die neuesten Entwicklungstrends

Zu Kodik gehen Telegram beitreten

Schließe dich einer Community von Entwickler:innen an, die gemeinsam wachsen! 💪

🎯Hör auf zu zögern

Artikel gefallen?
Zeit zum Üben!

Bei Kodik liest du nicht nur — du schreibst sofort Code. Theorie + Praxis = echte Skills.

Sofortige Praxis
🧠KI erklärt Code
🏆Zertifikat

Keine Registrierung • Keine Karte