2Brute2Best
🔥0

Maximum Subarray

Medium·LeetCode #53Basic Anchor
LeetCode
30-Second Mental ModelKadane's algorithm (Maximum subarray)
Complexity:O(N^3)→O(N)
Key Insight

Let cur be the largest sum of a run that ends at the current index. At each index, the best run ending here is either this number alone, or this number plus cur, whichever is bigger. Keep best as the largest cur seen so far.

Core Validity Invariant

cur is always the best sum of a subarray that ends exactly at the current index, so it is a valid candidate for the answer at every step.

01

Problem

You are given an integer array nums. Find a contiguous part of it, a subarray with at least one number, whose sum is as large as possible. Return that largest sum.

A subarray is a run of neighbouring numbers. You cannot skip numbers in the middle.

Input

An integer array nums of length n.

Output

One number: the largest sum of any non-empty subarray.

Example 1
Input: nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
Output: 6

The run [4, -1, 2, 1] adds up to 6. No other run of neighbours does better.

Example 2
Input: nums = [1]
Output: 1

The only subarray is [1].

Example 3
Input: nums = [5, 4, -1, 7, 8]
Output: 23

The whole array is the best run: 5 + 4 − 1 + 7 + 8 = 23.

Constraints
  • • 1 ≤ nums.length ≤ 10^5
  • • −10^4 ≤ nums[i] ≤ 10^4
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    The answer is a run of neighbours. If I know the best run that ends at index 4, how can it help me at index 5?

  2. 2.

    Can the best run be empty? What is the answer for an array with only one negative number?

  3. 3.

    If the run so far has a negative sum, is it worth keeping before I add the next number?

  4. 4.

    Must the best run end at the last index? Where else could it end?

  5. 5.

    How many runs end at one particular index?

03

Brute force approach

04

Better approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceAdd up every subarray from scratch and keep the largest sumO(N^3)O(1)
BetterFix the start, grow the end one step at a time, keep one running sumO(N^2)O(1)
OptimalTrack the best run that ends at each index: extend it or restartO(N)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “contiguous subarray”The answer is a run of neighbours. Think of the best run that ends at each index.
  • “largest sum”A sum can be updated in O(1): add the new number, or drop the old run and start again.
  • “at least one number”The answer can be negative, so the start value is a real number, never 0.
Contiguous subarray+maximize the sum+each index: extend or restart→Kadane's algorithm (Maximum subarray)

This is the anchor of the Maximum subarray sub-pattern. The length of the run is free, so the only decision at each index is extend or restart. The next three questions keep this rule and change the comparison: the smallest sum, the absolute sum, and one deletion.

10

Don't make this mistake

Pattern confusion: resetting to 0 when the sum goes negative
✗ int cur = 0, best = 0; for (int x : nums) { cur += x; best = max(best, cur); if (cur < 0) cur = 0; }
✓ int cur = nums[0], best = nums[0]; for (int i = 1; i < n; i++) { cur = max(nums[i], cur + nums[i]); best = max(best, cur); }

Resetting to 0 lets cur become an empty run. On the dry run [-2, 1, -3, 4, -1, 2, 1, -5, 4] it still prints 6, so the bug hides. But at index 2 it sets cur = 0, while the correct run ending there is −2. On [-3, -1, -2] it prints 0, but the answer is −1, the largest single number.

Adding every positive number
✗ int total = 0; for (int x : nums) if (x > 0) total += x;

This picks numbers from anywhere, so it finds a subsequence, not a subarray. On the dry run it gives 1 + 4 + 2 + 1 + 4 = 12, which skips the −3, −1 and −5 in between. The answer must be one run of neighbours, which is 6.

Checking only the last cur
✗ for (...) cur = max(nums[i], cur + nums[i]); return cur;
✓ best = max(best, cur); // at every index ... return best;

The best run can end in the middle of the array. On the dry run the last cur is 5, for the run [4, −1, 2, 1, −5, 4]. The best run, [4, −1, 2, 1], ends at index 6 and sums to 6.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like DP — Kadane / Subarray translate into production architectures and low-level memory mechanics.