Skip to content
FoundationVerified ImplementationLive Benchmarkable

Kadane's Algorithm

Finds the contiguous subarray within a 1D numeric array that has the largest sum in a single O(n) pass and O(1) space.

Quick Facts

Compact metadata for implementation and discovery.

Category
Optimization
Difficulty
Beginner
Family
Dynamic Programming
Tier
Foundation
Status
Verified
Review
Source Checked
Sources
1
Formulas
1
Relationships
1
Code example
Ready
Visualization
Ready
Aliases
Maximum Subarray Algorithm, Maximum Contiguous Subarray

Overview

Kadane's Algorithm solves the Maximum Subarray Problem in linear O(n) time using dynamic programming. At each index i, it decides whether to extend the best subarray ending at i - 1 or start a fresh subarray at i, tracking both the maximum sum and the [start, end] index boundaries.

Core Concepts

optimal substructureprefix gain resetsingle-pass O(1) space DP

Quick facts

Complexity

Runtime and memory behavior at a glance.

Best

O(n)

Average

O(n)

Worst

O(n)

Space

O(1)

Interactive Runtime & Memory Budget Calculator

Estimate wall-clock latency, operation count, and working memory for Kadane's Algorithm across input scales.

Input Scale N:
JIT-compiled JS/TS (~350M primitive ops/sec)
Est. Average TimeO(n)

428.6 µs

60 FPS Frame-Safe (<16ms)~150.0k ops
Est. Worst-Case TimeO(n)

428.6 µs

60 FPS Frame-Safe (<16ms)~150.0k ops
Est. Working MemoryO(1)

128 B

L2/L3 Cache FriendlyN=100,000

When to Use

  • Single-pass O(n) dynamic programming algorithm that finds the contiguous subarray with the maximum sum in a 1D numeric array.
  • Use Kadane's Algorithm to find the highest-sum contiguous slice of a signed array in O(n) time.
  • Use it instead of O(n log n) divide-and-conquer or O(n^2) prefix-sum scans.

When Not to Use

  • Avoid plain Kadane when subarray length is constrained to [L, U] (use a monotonic deque over prefix sums).

What It Does

  • Maintains the maximum sum ending at the current position (curSum = max(x, curSum + x))
  • Tracks the global maximum sum and [start, end] indices in a single pass

Use Cases

  • Finding maximum-gain intervals in financial return or telemetry time-series
  • 1D dynamic programming subroutine in 2D maximum submatrix search
  • Signal burst and peak window detection

Inputs

  • 1D array of signed numbers (positive, negative, zero)

Outputs

  • Maximum contiguous subarray sum and [start, end] indices

Key Formulas (1)

Kadane Recurrence

dp[i] = \max(A[i],\; dp[i−1] + A[i])
dp[i] = \max(A[i],\; dp[i-1] + A[i])

Best contiguous sum ending at index i.

Pseudocode

  1. 1.Initialize maxSum = curSum = values[0], start = end = tempStart = 0
  2. 2.For i = 1 to n - 1:
  3. 3. If values[i] > curSum + values[i], set curSum = values[i] and tempStart = i
  4. 4. Else add values[i] to curSum
  5. 5. If curSum > maxSum, update maxSum = curSum, start = tempStart, end = i
  6. 6.Return { maxSum, start, end }

Verified Implementation & Unit Tests

Verified Implementation

Tested TypeScript and Python 3 implementations paired with unit tests covering edge cases, duplicate keys, and boundary conditions.

/**
 * Kadane's Maximum Subarray — Single-pass O(n) maximum contiguous sum & span
 * Time: O(n) | Space: O(1)
 */
export function kadaneMaxSubarray(values: readonly number[]): {
  maxSum: number;
  start: number;
  end: number;
} {
  if (values.length === 0) return { maxSum: 0, start: -1, end: -1 };
  let maxSum = values[0], curSum = values[0];
  let start = 0, end = 0, tempStart = 0;
  for (let i = 1; i < values.length; i++) {
    if (curSum + values[i] < values[i]) {
      curSum = values[i];
      tempStart = i;
    } else {
      curSum += values[i];
    }
    if (curSum > maxSum) {
      maxSum = curSum;
      start = tempStart;
      end = i;
    }
  }
  return { maxSum, start, end };
}

Canonical Example

Input
[-2, 1, -3, 4, -1, 2, 1, -5, 4]
Output
maxSum = 6, subarray = [4, -1, 2, 1] (indices 3..6)
Explanation
The window resets at index 3 (value 4) and accumulates through index 6 to reach sum 6.

Implementation Notes

  • Track tempStart whenever curSum resets to values[i] so the exact [start, end] slice can be recovered.

Common Pitfalls

  • Initializing maxSum = 0 returns 0 instead of the largest negative element on all-negative arrays.

Interactive Mechanism Walkthrough & State Debugger

Array Partition & Ordering Trace

Sliding contiguous window expanding when prefix gain is positive and resetting when prefix sum drops below zero.

38
[0]
14
[1]
52
[2]
23
[3]
61
[4]
19
[5]
44
[6]
29
[7]
step1 / 6
cursor i0 (val=38)
pivot / key61
sorted prefix0 / 8 items
invariantPartitioning prefix
Step 1 of 6: Initialize maxSum = curSum = values[0], start = end = tempStart = 0
array-sort

Notes

Handles all-negative arrays cleanly by initializing maxSum and curSum to values[0] instead of 0.

Sources (1)

What each reference supports for this entry.

Bentley (1984) — Programming Pearls: Algorithm Design Techniques

Article

Published Jay Kadane's linear-time maximum subarray algorithm.

Open source

Explore Next

Good next jumps from the relationship graph, ranked for useful discovery.

Improves onMerge Sort

Solves maximum subarray in O(n) time vs O(n log n) divide-and-conquer.

Related Algorithms

Tags

Dynamic ProgrammingSubarrayLinear TimeClassic