0Pricing
Coding Interview Prep · Lektion

Maximales Teilarray und Teilarray mit maximalem Produkt

Wenden Sie Kadane's Algorithmus auf maximum-sum-subarray an und erweitern Sie ihn für die Produktvariante, indem Sie sowohl Maximum als auch Minimum verfolgen.

Maximales Teilarray und Teilarray mit maximalem Produkt ist eine kostenlose Coding Interview Prep-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Coding Interview Prep-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.

Problem des Teilarrays mit maximaler Summe

Beim Problem Maximum Subarray sollen Sie das zusammenhängende Teilarray innerhalb eines eindimensionalen Zahlenarrays finden, dessen Summe am größten ist. Im Beispiel [-2, 1, -3, 4, -1, 2, 1, -5, 4] ergibt das Teilarray [4, -1, 2, 1] die maximale Summe 6. Ein Brute-Force-Ansatz mit O(n²) prüft alle Teilarrays, aber der Kadane-Algorithmus löst das Problem in O(n).

nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
# Brute force: O(n^2)
max_sum = float('-inf')
for i in range(len(nums)):
    curr = 0
    for j in range(i, len(nums)):
        curr += nums[j]
        max_sum = max(max_sum, curr)
print(max_sum)  # 6

Intuition zum Kadane-Algorithmus

Der Kadane-Algorithmus durchläuft das Array einmal und verwaltet dabei eine laufende Summe current_sum. Bei jedem Element entscheiden Sie: Ist es besser, das bestehende Teilarray zu erweitern oder mit diesem Element neu zu beginnen? Wenn current_sum negativ wird, würde es jedes zukünftige Teilarray nur verschlechtern, daher beginnen Sie neu. Die Rekurrenz lautet current_sum = max(num, current_sum + num).

def max_subarray(nums):
    max_sum = current_sum = nums[0]
    for num in nums[1:]:
        # Extend or start fresh?
        current_sum = max(num, current_sum + num)
        max_sum = max(max_sum, current_sum)
    return max_sum

nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
print(max_subarray(nums))  # 6

Nachverfolgen des Kadane-Algorithmus

Verfolgen wir den Kadane-Algorithmus für [-2, 1, -3, 4, -1, 2, 1, -5, 4]: Wir beginnen mit curr=-2, max=-2. Bei 1: curr=max(1,-2+1)=1, max=1. Bei -3: curr=max(-3,1-3)=-2, max=1. Bei 4: curr=max(4,-2+4)=4, max=4. Bei -1: curr=3, max=4. Bei 2: curr=5, max=5. Bei 1: curr=6, max=6. Bei -5: curr=1. Bei 4: curr=5, max=6. Der Algorithmus identifiziert korrekt das bei Index 6 endende Teilarray als optimale Lösung.

def max_subarray_trace(nums):
    curr = max_sum = nums[0]
    for i, num in enumerate(nums[1:], 1):
        new_curr = max(num, curr + num)
        max_sum = max(max_sum, new_curr)
        print(f'i={i}, num={num}, curr: {curr}->{new_curr}, max={max_sum}')
        curr = new_curr
    return max_sum

max_subarray_trace([-2, 1, -3, 4, -1, 2, 1, -5, 4])

Das tatsächliche Teilarray zurückgeben

Wenn der Interviewer Sie auffordert, das Teilarray selbst zurückzugeben (nicht nur die Summe), müssen Sie Start- und Endindizes verfolgen. Wenn Sie neu beginnen (weil num > current_sum + num), aktualisieren Sie einen temp_start. Wenn Sie max_sum aktualisieren, speichern Sie temp_start als start und den aktuellen Index als end. Dies fügt demselben O(n)-Algorithmus einen O(1)-Zusatzaufwand hinzu.

def max_subarray_indices(nums):
    max_sum = curr = nums[0]
    start = end = temp_start = 0
    for i in range(1, len(nums)):
        if nums[i] > curr + nums[i]:
            curr = nums[i]
            temp_start = i
        else:
            curr += nums[i]
        if curr > max_sum:
            max_sum = curr
            start, end = temp_start, i
    return max_sum, nums[start:end+1]

print(max_subarray_indices([-2, 1, -3, 4, -1, 2, 1, -5, 4]))
# (6, [4, -1, 2, 1])

Problem des Teilarrays mit maximalem Produkt

Das Problem Maximum Product Subarray ist aufgrund von negativen Zahlen schwieriger als die Summenvariante. Zwei negative Zahlen ergeben beim Multiplizieren eine positive Zahl, sodass ein sehr negatives Produkt nach der Multiplikation mit einer weiteren negativen Zahl zum Maximum werden kann. Für [2, 3, -2, 4] lautet die Lösung 6 ([2, 3]). Für [-2, 0, -1] lautet die Lösung 0. Wir müssen bei jedem Schritt sowohl die maximalen als auch die minimalen Produkte verfolgen.

nums = [2, 3, -2, 4]
# [2,3,-2,4]: products [2, 6, -12, -48]
# subarrays: [2]=2, [2,3]=6, [3]=3, etc.
# max is 6 from subarray [2,3]

nums2 = [-2, 3, -4]
# [-2]*3*[-4] = 24
# negative*negative=positive!
print('Expected:', 24)

Maximale und minimale Produkte verfolgen

Die entscheidende Erkenntnis lautet: An jeder Position ist das aktuelle maximale Produkt eines von num, max_so_far * num oder min_so_far * num (letzteres ist hilfreich, wenn eine negative Zahl das Minimum in ein Maximum umwandelt). Entsprechend gilt dasselbe für das Minimum. Aktualisieren Sie beide Werte cur_max und cur_min gleichzeitig anhand der vorherigen Werte, damit Sie innerhalb desselben Schritts nicht bereits aktualisierte Werte verwenden.

def max_product(nums):
    max_prod = min_prod = result = nums[0]
    for num in nums[1:]:
        # All three candidates for new max
        candidates = (num, max_prod * num, min_prod * num)
        max_prod, min_prod = max(candidates), min(candidates)
        result = max(result, max_prod)
    return result

print(max_product([2, 3, -2, 4]))    # 6
print(max_product([-2, 3, -4]))      # 24
print(max_product([-2, 0, -1]))      # 0
print(max_product([-2]))             # -2

Warum min_prod wichtig ist

Betrachten Sie [-3, -10, 5]. Nach der Verarbeitung von -3: max=-3, min=-3. Nach -10: Die Kandidaten sind (-10, 30, 30) → max=30, min=-10. Nach 5: Die Kandidaten sind (5, 150, -50) → max=150. Ohne die Verfolgung von min_prod würden Sie den Vorzeichenwechsel übersehen, der auftritt, wenn ein stark negatives Minimum mit einer weiteren negativen Zahl multipliziert wird. Berechnen Sie max und min immer aus denselben vorherigen Werten, um einen Fehler durch das Lesen veralteter Werte zu vermeiden.

def max_product_traced(nums):
    max_p = min_p = result = nums[0]
    for num in nums[1:]:
        prev_max, prev_min = max_p, min_p
        max_p = max(num, prev_max * num, prev_min * num)
        min_p = min(num, prev_max * num, prev_min * num)
        result = max(result, max_p)
        print(f'num={num}: max_p={max_p}, min_p={min_p}')
    return result

max_product_traced([-3, -10, 5])
# max_p after -10: 30 (flip!)
# max_p after 5: 150

Nullen setzen das Produkt zurück

Eine Null im Array setzt beide laufenden Produkte auf null zurück und teilt das Array damit effektiv in unabhängige Teilarrays. Wenn num = 0 gilt, sind sowohl max_prod * 0 = 0 als auch min_prod * 0 = 0 gleich 0. Somit werden alle drei Kandidaten zu 0, und das bisherige Maximum bleibt erhalten. Es ist kein Sonderfallcode erforderlich — die allgemeine Formel verarbeitet Nullen ganz natürlich.

def max_product(nums):
    max_p = min_p = result = nums[0]
    for num in nums[1:]:
        cands = (num, max_p * num, min_p * num)
        max_p, min_p = max(cands), min(cands)
        result = max(result, max_p)
    return result

# Zero splits array into independent subarrays
print(max_product([3, -1, 4, 0, 2, 5, -1]))   # 10 (2*5)
print(max_product([0, 2]))                       # 2
print(max_product([-1, 0, -2]))                  # 0

Alternative: Produkt-Sweep von links nach rechts und von rechts nach links

Ein alternativer Ansatz durchläuft das Array von links nach rechts und von rechts nach links und setzt das laufende Produkt bei einer Null auf 1 zurück. Das Teilarray mit dem maximalen Produkt überschreitet niemals eine Null. Wenn eine negative Zahl die Situation in eine Richtung verschlechtert, erkennt der umgekehrte Durchlauf den Vorzeichenwechsel. Dieser Ansatz ist elegant, aber die Methode zur Verfolgung von min/max wird in Interviews häufiger erwartet.

def max_product_sweep(nums):
    result = max(nums)
    left = right = 1
    n = len(nums)
    for i in range(n):
        left *= nums[i]
        right *= nums[n - 1 - i]
        result = max(result, left, right)
        if left == 0: left = 1
        if right == 0: right = 1
    return result

print(max_product_sweep([2, 3, -2, 4]))   # 6
print(max_product_sweep([-2, 3, -4]))     # 24
print(max_product_sweep([-2, 0, -1]))     # 0

Kadane vs. Produkt: Die wichtigsten Unterschiede

Summen- und Produkt-Teilarrays unterscheiden sich in wichtigen Punkten. Bei Summen sind negative Zahlen immer schädlich, daher beginnen Sie nach dem Greedy-Prinzip neu. Bei Produkten sind zwei negative Zahlen hilfreich, deshalb müssen Sie beide Extreme verfolgen. Außerdem sind Nullen für Produkte ein Abbruchpunkt, während sie für Summen nur mäßig schädlich sind. Weisen Sie im Interview ausdrücklich auf diese Unterschiede hin und erklären Sie, warum die Verfolgung des Minimums erforderlich ist, bevor Sie Code schreiben.

# Max Sum Subarray: O(n) time, O(1) space
def max_sum(nums):
    curr = result = nums[0]
    for n in nums[1:]:
        curr = max(n, curr + n)  # restart or extend
        result = max(result, curr)
    return result

# Max Product Subarray: O(n) time, O(1) space
def max_prod(nums):
    lo = hi = result = nums[0]
    for n in nums[1:]:
        lo, hi = min(n, lo*n, hi*n), max(n, lo*n, hi*n)
        result = max(result, hi)
    return result

print(max_sum([-2, 1, -3, 4, -1, 2, 1]))   # 6
print(max_prod([-2, 3, -4]))               # 24

Komplexität und Tipps für Interviews

Sowohl der Kadane-Algorithmus (maximale Summe) als auch die Min-/Max-Verfolgung (maximales Produkt) benötigen O(n) Zeit und O(1) Speicher. Wichtige Tipps für Interviews: (1) Erwähnen Sie bei der maximalen Summe die Divide-and-Conquer-Alternative mit O(n log n), um Ihre Kenntnisse zu zeigen. (2) Betonen Sie beim maximalen Produkt, dass Sie min_prod und max_prod gleichzeitig anhand der vorherigen Werte aktualisieren, damit Sie keine veralteten Daten verwenden. (3) Klären Sie immer: Darf das Array leer sein? Muss das Teilarray nicht leer sein? (Ja, es muss konventionsgemäß nicht leer sein.)

# Both run O(n) time, O(1) space
# Kadane handles: all negative (returns least negative)
# Product handles: zeros (resets naturally), negatives (tracks both extremes)

nums_all_neg = [-5, -2, -8]
print('Max sum (all neg):', max(max(nums_all_neg[0:1]),
      max(x for x in nums_all_neg)))  # -2
# Correct: return the maximum element when all are negative

Kurzer Test

Testen Sie Ihr Verständnis der Konzepte aus Data Structures & Algorithms — Coding Interview Prep in dieser Lektion.

Zusammenfassung der Lektion

In dieser Lektion haben Sie Folgendes gelernt: Der Kadane-Algorithmus löst das Problem des Teilarrays mit maximaler Summe in O(n), indem er bei jedem Element zwischen Erweitern und Neustart wählt, für das Teilarray mit maximalem Produkt müssen aufgrund der Vorzeichenwechsel bei negativen Zahlen sowohl die minimalen als auch die maximalen laufenden Produkte verfolgt werden und Nullen setzen das laufende Produkt ohne Sonderfallcode auf natürliche Weise zurück. Als Nächstes untersuchen wir das Word-Break-Problem mithilfe einer eindimensionalen DP-Tabelle.

Häufig gestellte Fragen

Ist die Lektion „Maximales Teilarray und Teilarray mit maximalem Produkt“ kostenlos?

Ja — der vollständige Text von „Maximales Teilarray und Teilarray mit maximalem Produkt“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Coding Interview Prep-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Maximales Teilarray und Teilarray mit maximalem Produkt“?

Wenden Sie Kadane's Algorithmus auf maximum-sum-subarray an und erweitern Sie ihn für die Produktvariante, indem Sie sowohl Maximum als auch Minimum verfolgen. Du übst Coding Interview Prep mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Coding Interview Prep zu starten?

Keine Vorkenntnisse erforderlich. Coding Interview Prep auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Maximales Teilarray und Teilarray mit maximalem Produkt“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Coding Interview Prep-Lektion Code schreiben und ausführen?

Ja. Jede Coding Interview Prep-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. House Robber: Rekurrenz aus Nehmen oder Überspringen
  2. Maximales Teilarray und Teilarray mit maximalem Produkt
  3. Word Break und String segmentieren
  4. Decode Ways und Pfade zählen
← Zurück zu Coding Interview Prep