Kadane's algorithm finds the largest sum of any contiguous slice of an array in a single left-to-right pass. The trick is a running-sum dynamic program: at every position you only need one number — the best sum that ends right here — and you carry it forward, restarting whenever the past is dragging you down.
Core idea. Keep two values as you scan. cur is the best subarray sum ending at the current
index: cur = max(x, cur + x). best is the largest cur seen anywhere. For
nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] the answer is 6, from the slice [4, -1, 2, 1].
The classic problem: Maximum Subarray. Among all contiguous slices, return the one with the greatest sum. A brute-force check of every slice is O(n²); Kadane does it in O(n).
Intuition
Walk along the array carrying a running total. At each new element x you face one decision: is the sum you have been building still worth keeping, or should you throw it away and start fresh from x?
If cur + x is bigger than x by itself, the past is helping — extend the window. If x alone is bigger, the past total was negative baggage — restart the window at x. That single comparison, max(x, cur + x), is the whole algorithm. Every time cur reaches a new high, you stamp it into best.
Walk through it
Step through the animation on the right. The i pointer scans nums left to right. The cur and best labels update at the top; the highlighted cells show the window that currently sums to cur (the locked best window stays marked).
Start with cur = best = -2. At index 1 (value 1), cur + x = -1 but x = 1 is bigger, so the window restarts at 1 and best jumps to 1. Index 2 (value -3) drags cur down to -2. At index 3 (value 4), -2 + 4 = 2 loses to 4 alone, so the window restarts again at 4, and best becomes 4. From there the window only grows: -1, then 2, then 1 push cur up to 3, 5, 6 — each a new best. Index 7 (value -5) drops cur to 1 but best stays 6. Index 8 (value 4) lifts cur to 5, still under 6. Final answer: best = 6, the slice [4, -1, 2, 1].
The code, line by line
def max_subarray(nums):
cur = nums[0]
best = nums[0]
for x in nums[1:]:
cur = max(x, cur + x)
best = max(best, cur)
return best- Lines 2–3 seed both values with the first element, so the answer is always a non-empty subarray.
- The loop starts at the second element (
nums[1:]) because the first already initializedcurandbest. - Line 5 is the heart of it:
max(x, cur + x)either extends the running window or restarts it atxwhen the carried sum has gone negative. - Line 6 records the running maximum —
curis only the best ending here, so we keep a separatebestfor the answer. - We never store the slice itself, only its sum; tracking the start and end indices is a small extra bookkeeping step if the actual subarray is needed.
Complexity
| Case | Time | Notes |
|---|---|---|
| Time | O(n) (moderate) | one pass; constant work per element |
| Space | O(1) (fast) | only cur and best are kept |
O(1) (fast)Each element is visited exactly once and does a single max comparison, so the total work is linear. Nothing about the array is stored beyond two scalars, making it the textbook example of an O(1)-space running-sum DP.
When to use / pitfalls
Reach for Kadane whenever a problem asks for the best contiguous run under a sum — maximum subarray, maximum product subarray (track both min and max), best time to buy/sell stock once, or maximum circular subarray. The signal: you want the optimal contiguous slice and a per-element decision of 'keep building or start over' is enough.
Two traps. First, initialize with the first element, not 0 — seeding best = 0 returns 0 for an
all-negative array like [-3, -1, -2], where the correct answer is -1. Second, keep cur and best
separate: cur can dip after a peak, so returning cur instead of best loses the maximum.
Practice
For nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4], what is cur right after processing index 6 (value 1)?
1. What does cur represent at each step?
2. When does the window restart instead of extending?
3. Why must best be tracked separately from cur?
4. For an all-negative array like [-3, -1, -2], what does correct Kadane return?